// ==UserScript==
// @name    Facebook Mafia Wars Autoplayer
// @namespace   mafiawars
// @description   autoplayer for the mafia wars game I modified code from Blannies Vampire Wars script http://userscripts.org/scripts/show/36917
// @include   http://apps.facebook.com/inthemafia/*
// @include   http://apps.new.facebook.com/inthemafia/*
// @version 0.8.r336
// @contributor StevenD
// @contributor CharlesD
// @contributor Eric Ortego
// @contributor Jeremy
// @contributor Liquidor
// @contributor AK17710N
// @contributor Fragger
// @contributor <x51>
// @contributor CyB
// @contributor int1
// @contributor Janos112
// ==/UserScript==


var SCRIPT = {
  url: 'http://userscripts.org/scripts/source/43573.user.js',
  version: '0.8.r336',
  name: 'inthemafia',
  appID: 'app10979261223',
  presentationurl: 'http://userscripts.org/scripts/show/43573',
  controller: '/remote/html_server.php?&xw_controller=',
  action: '&xw_action=',
  opponent: '&opponent_id=',
  user: '&user_id='
};

// Register debugOnOff with Greasemonkey
GM_registerMenuCommand( 'FB Mafia Wars Autoplayer - Turn Debug Log '+(GM_getValue('enableDebug')  == 'checked' ? 'off' : 'on'), debugOnOff);
GM_registerMenuCommand( 'FB Mafia Wars Autoplayer - Clear Saved Values', clearSettings);

function clearSettings() {
  if(typeof GM_listValues == 'function' &&
     typeof GM_deleteValue == 'function') {
    var values = GM_listValues();
    for (var i in values) {
      GM_deleteValue(values[i]);
    }
  } else {
    alert('In order to do this you need at least GreaseMonkey version: 0.8.20090123.1. Please upgrade and try again.');
  }

  loadHome();
}



//create data uris for mini icon usage
var searchIcon = '<img src="' +
                    '' +
                    '/xk+HmvYcMj54+X/n9x4/oCD+Pv1gNWLVlp6GYiMhJQ20NVm4uDoTMfwaGf///MZy5fIPh9Zs3tf5uji1YDdi67/BSaUnJKDUFGQYmJiaw7SDd//79Z/j77x/Di9fvGO4+ePTh4+fP4mE+br8wDNh+4OhDTRVlOU' +
                    'F+XgYOdlaIAUDbQZp//vrN8OrtB4b3Hz8yPHzy1BhowDkMA3YePPZCR0NNnJebk4GdlRXsiv9A+PfvP4Yv374zfPryjeHdhw+gsLAK9nQ+js0Lewy1NZ15ebgYWFlYGFiYmcDO//P3L8M3YEB+/faD4eHTp3+ePH' +
                    '8pFuXv+R7DAGD0hasoyK1QlkeEwf//EBf8+PWL4e37jwy37z9Y7uNsF4UvGherKcnHyEtLMjAzM4MNALng5Zt3DM9fvWa4/+BhSWyIfy9OAxav28LEy81VwsvDUyolLioCcsW7Dx9/vf/4adWLl6+vXzt/qmXz+r' +
                    'WHGJmYfG7evPkFwwAYmL96IwsTI6MG0BXsQFfcjg3y+QQSNzO3OMzLL2Dz9OH9o0A/ety4ceMLVgNwAR1tbT5efv4dXDx8lk8fPTgKFPIEGvKZaAMghmgBDRHAMIRoA3AZQpIBUEN4gYbsBBny8O7tvSQbAA0TXg' +
                    '4u7g2fP33YBwCb9/irlkMH+QAAAABJRU5ErkJgggo=' +
                    '" />';

var lootbagIcon = '<img src="' +
                    '' +
                    'poSv///yH5BAEAAB8ALAAAAAAQABAAAAWB4CeOk1Y0UHeMrHgAUZU4Wds2gcKo9thxl0ePNUlUKoPVEGLZYDaBZK9gsTwJgcig11h4KQSHQiJscSjoRFgi2bIOsoRxPXCPDoQ4QSAeXFp4BIICAQ5tfywFAouEDh' +
                    'FtBm8Bk4xZCgoPSh8ZARcKk4UKjgiaHyoFDAaqBh4MpCIhADs=' +
                    '" />';

var tabSelectedImage = '<img src="' +
                    '' +
                    '7CRfEyUa/ymwRlwxPxc3G5hJcBxsgEtjDHZ6W1I9lqR9s3xvReU1oyRjr7ZbIzFNopm7OSnVnNuDVjr3VXeSVvJngudRaAKzeGPlM4Pk1FkSSPgk1TiJYkKoycdp+ac00iKJRBpmNYZUqjeqhlIjqsf655aIZqXU' +
                    'mlJryXe4qjhE9fKj+SnZ62g79uMcEsw3K+rThOz33at2HNK9nX4DVqddC/QmNdw75nudMr6tPSoutMA+vBP/jzy3Y3jcL5SyRq0hOAgvKka2OsFUNm7BracsIMD71W1iZqMvcGiZgQ/iE8egG5DMcpZxjFjNzzjp' +
                    'kmVRLwWarCZ82UHjTxMHIYr1giSTkD1hr2ElnKTrs4Ii1ki+CmPkQGPkrqp5qWNjw+1HTmiWfWqK5+0imI5Aaieiq3KQsFFo+UkF/RtGtG8eTKSjXnEj0mLG0scrdMXcL2dE7YVEiHCsU1hJqPKrKUEnlsRuHan1' +
                    'p7xYuclh1lrUPfTuKmaINMLDJ7xTwLNhIhC1E+NovCemLsrEFjOgKShJ+R1yUu71wT0lJZ3UCs5B0kRUDq21QmyByAhN+b5zF7sIHNY7sJ6h9OB/CNU7ppkdGdLwEgczx18+zZkE89oD14C+/VD3sffbxp+dWV/l' +
                    'cfcvCpxx5QxOkWn3bOZVCfc28RoIF24zknIQAEvEcdIc51OMuG7uHTYH/UPThgABIG16GHdYDYYA8HlDBAhiLWWKKE7lVAAIQWUlDfeTN2BJ4AF/4YogU7rnEAbPXd6CCATAZXpIozYpChjCVuuGOTP9aXIZLBze' +
                    'jjjkRukKR7Mh6AT5D4+eglPlcSCWGT4xEgwZkP1kkBkRuKGZ+Z1BGwI4qE7HhAAU0uiaGWTcrpp6Axgdeon0HG16igJQxKqHZJQvrnBBlOsCR+oYpJo4VSEHDAgWp6iSifGWC6qIxXUirTqTOKKMCrud6Y6qqz1n' +
                    'njng1maCcAB5B5paAW/iRrLKYzFiChtDOquiMBBaQ5ZqbLqolitnxK4aqhKTpb7ZYxsjeooGRKi+KgB6gJawDOEllAjPFScGiu8eJzL3XJ6lurtwOMKiaRgtaH6HhLQhjvtfcKkC+yJhLc8IxqWouiARYGjK1ziL' +
                    'Lr8b+7tiqtoYhimG0A1L6baIiq7kuAAc5m+O8AIQs6cgkts2sBrzRK6yyiOCeLM9HmnoxxvwUQrbTS+77LM7MRD2CAzkY7G6+aTdeXdMJRY1pnARsgGrDVhy5pAMcAUCvo1bty7BwCquL8LNwFyM3roRIeYIDX/f' +
                    'pNHQJc/00313fvmHcPe7u7tapX+41oAQkI2rQB/ohivuPV0uaNr+dWSysA59jSLDHbN9+boeloq1oA4QQQDrrmo2NbOr6ot0rzz1jPiHm8a8OOAM0IIDBj5clePnPe9xZ/vLXKv454D2tHbEACPcCObQLSYv678w' +
                    'Qgj23e2BJud8ccB4BAtggkQF0Cw0t/79o0U57h8F4y4Dr9h1Y+AP7/S94B1oczBkjPe9jSn9XwRwD9HYp/9vvf3wKIrQGGDHb9m1nx/LaAwyXgah9sGgP8FryrYc6A4cNcAUZIv+HNzH0B4N6M1ne9AySgcgIYHv' +
                    'AYQDgDIACFIVwhCX1oQhjKMHY+fN/8EpAsHhYPcwogIuZ+mKwFhIx7CGiA/hRfN0ICWPF49/KbAXOYABQN74OxW0CGOigtBCwgAVEc3hS7+MXwhdEAY2zf0QqgRgF0MHYKiNcTDRBFEVavfX+D4/8KUMgVHvKDA1' +
                    'CkAAyYrOL1kHv3YsDabGjF2MHvUI3U5BQhKUlKxq54mfyd5uAnu0DeUAGVU4AD36hJJ5IQlgSQpapoiccNElJNVGxgAlDIADUOoJOU++IrYznLYfayh4H8Xxd5yMRjGu+TwhyhAijHxzeuUAFWXMAC1PTGH3aTew' +
                    'wAZzfJub7XKYBuCNjm2ooJTwVQx5uR3Cb3xIlOdYqTnU2LZz1fGM+8RTF2DUgmG8G5tijeMAEdtKEC/rR4AIYS8no3jCgc1QRLEG5QoIjyJh61mEtwrs+iDs0o4TY6gI6GD5XxtOEB2GgAcTJyeD9cgCYVIM8Onh' +
                    'R++tQpIXuKSliuL52JrKY4cZlO5zTAhQ2wog+LuVOi/vSoUYxkNd/5wagyr5wTXZsDrlfTD7bvnRUNZPgcgMg3+hCOhONpsraZwHcOgAEkZaQmZ5rQXDYgigYY6wfdeta4qpWu3zQeXlP5TqkKtHg81aYmCfDUDi' +
                    '4AlwlwgE4rOtnKuhGzDdgRLJsGS/gF9qkBkCUUOxpPWXL2ap69bOUSEFoBjJaRNyweRXUZ2G0W4KmQde0CHEA5B6CxAZoM7giH/lvc4xpwpH+baLzAObMDNOABNFOAAxSALeC2drnEzaxz84bX6DZgupREoxvfCM' +
                    'enBhaLshzsO73ogEi+150MkC/dhlufsUqLoZRLaADSqb/A8rO9wzMufvVL3/5qDsC0zZZOw/fUQ411qA3gXgMSat0nmpSRE9Uwh4FLSDYu4LwtDe0AMkwzvOoPAQ54gOwuzNMM/3bEHjYxiieaIRYfwMUnVq0DHH' +
                    'AoGRsQnDs1LmVxqQAjM1Ko2q3cX2Np2hMzUbsZoqcX/yrUIRfZnEgmpJKnnMsqZ7iiDsjyH0mKV51eNsOUpahxPxhi+sJ5wzSbMyHhPNwYOYCOqs3sNfPaVeZi1hnPB9BznfssgD9XMdBsjeQIGfCABaxNxmdFLp' +
                    'qbFtWr8bR47dUmcX9r6ZISbrgIAAAcs4VcHp540gao9KVBPVFRc7rUn54pW1W9TQG02o0NiAAAOw==' +
                    '" />';

var playIcon = '<img src="' +
                    '' +
                    'GCYShWfNRHh1faN7aeexkinuTm3pt77ne+851zBPxnW1tbCVmSxxVVuU3XRKPRAK0N0zRf2ba9kEwmN/71F44O2WxWlCRpGj5x4sPXVXk9m0OlWuVvweZmJOLduDiYclzbmnNddyqVSnnHAD+3t0VFUV9ktT/336' +
                    'x8RGtLEKqiwOfz0WsD9XoDpmWhXNnH6OUhREPBZWIzxkA4gKZpM7/+FDMrn78hEg5BlmVIokgABwQZgOu5sG0HeqGIKxcGEQ6os4lEYlLY2dlJSIq6+vL1e7k9HIaqKvyzKAogLQ4B6nBcD7bjwLJs5PcKuDNyya' +
                    'ntVwYEXddn1nO7Gb1ooCXQTAAyOVl49vw5boyO4kwySYkKTEh4Xp1SsWHsVxEJtaA7HJwVjLLx9tPaZjrQ5Kdsma+AKok3//gJP/f39+N6Oo1otJPfD6uCas3E2XjXO8EwjN9ffmSjHadCqJkWahTdILGWlpag+p' +
                    'sQaGmjyC66OtsxfO0q2iMRNFGa+b0iBuJdGgFUfn/fzEXDbUEuFqNXKpex+HQJ/qZmBFpD8FwXsc4IRobTiB0yKZQMnO7u0IRKpfJ2bVtL+xWZq65QBaq1Kh48fASBysg0uHVzFD2xGC+pRZWoNw72eEfonVAsFm' +
                    'f0cjVTpsgqfVZkCY5jY35hEffu3sHQ+XNcPIdY2I7LK8F2JnhAwqyQz+cTlOvq6lZOZgAyAYhEkTURY8PMozK6ngeXgdCybBepvi7HKJcGeKcUCoUZ061ncprOGRz0gY/netRIRyCMQQ/pIXjObCwWm+Qeu5omqn' +
                    '7/i5rt3s/t6jy66PsHoNHgzcRSYZ9FeMuWaY71xePe8TAxEFlRpiVZmdBLhlwy9nn3MZMlEW3BAMKtAceq1eZsx57q7e31TkzjkTFNaBbGaTKPx5lsg4aHjzPRPjHOfwGdsIJvkkplkQAAAABJRU5ErkJgggo=' +
                    '" />';

var infoIcon = '<img src="' +
                    '' +
                    'wSjcQj+INzrfbu2nu0d1drd293ze4FZZJNdnZmPzO/38yPwn/N5/PbOY5dJwiCS9N1u64DFHSfKIrtsqycmzChxDd0PvX7xe/3MzTNNiRF7PK2dXDPX/kQjSbNsVGjMjG73IEVNWUKz6aaNVWtLy0dr/4BOju7GJ' +
                    '7n224/+VZ9/OxjWMgP3DAO+u9VyIsiKeiPDmLr+irMK8+7JstyrYGYQE8g2HjnWaen5fxT5FizkaJpVDpt2La83ASOnm7HK38ErKYhHBzAtjWVqHKObhpf4qijurt77AmJ/rx4y0UuZ8xIKAwNjaYwf+Y47HNXmE' +
                    'B9yz087IyCUTVwBIkE+nGlpVYRKKmUCofDjQe8bzztb/xghwsAAUCArEwBedkZJhDoSyChpACNxKKqUEUZrrIibK2e2ETF4/EX5Z5bFRkCC8gyARhIZKJragFOrp1tAjsO3ca9njgEhnRSGiDwEKUUHu11vaRiA/' +
                    'GgY/t1q91hhdY/gO+RQYQHFbjnlMC7ea4JrG+4idYPQeRm8CjIyQRtyYbvSxAfDy0IpYGdN6w2xxh86fuBRKTf3Ka7shjejZVp4MAttH7qI6ExyMrNRnFuJvxfA/h4kADJZPKFs/5uRYIbhkDSCIGEQm6P25kP7+' +
                    'oZaeDwfbR+F83cIKUiL4tHliziuWceCSEWa/Rc+eA52xGERtFmDozHPbMA3pXT0kDzwzRATsDYHa1r2OC0om5hcRPV29tnj0jU52n773Myy5nbBLkH7lmF8K6angaOPEBr1480oKngFQUde1zKCOpnqXmRItFY46' +
                    'XXQc+my28BlgBkJ0vL8nGiZooJ7D7zFBe7CUBWBjnOU8umYsmkkU2FBfl1JhAKhRheENouvA5Vb7/6DrJx3hQ1pFR0My886R4jaM1kyzVJkmpttiL1TzEZCMvxDb2ivuvko2/czfdBdMVEc6zQMhyLJluxucqmWF' +
                    'i1OaXI9UVFhX+LaWgzcmKUM8dxLkXV7cY3htJ9pJTbJVk+NzY/759y/gUON2pDlqRajwAAAABJRU5ErkJgggo=' +
                    '" />';

var attackIcon = '<img src="' +
                    '' +
                    'ccFhsYGf/TJaeRO9PCav/fYqeWLP/UE//hRv+0DvC6QqeDDrWiHPecAP/GCtGeAoVXCvDcXKebSdOwWLF3CP/ic//sdvWnAIRuDWMtB3toDXYuAnU/CqJgAm9KDXBZDXtrLf///yH5BAEAAD8ALAAAAAANAA0AAA' +
                    'Z3wJ+wAxP+FiqjkkY6vnBK48HkEwl6xo4UIUCUbEJLaMbhjEASTBrd+qUGgQGLQs8UIB6hb9Co+CsPOx9CCzEBDRmJCg8FPEcoJzU1BAQ1ERo7Gi4yExc8BgYMEQk3Dg4bSisJEAkADlFCDDkfF66wFgl5PzqoQk' +
                    'EAOwo=' +
                    '" />';

var closeButtonIcon = '<img src="' +
                    '' +
                    'AGe9hgT0P6KlTX+DBh6WAi00otDhZlXcKwBspo+9i8+DSHvraQMlYznViVjuYhbWY3blNzk9zk3mubP/deH0buGoJuE/SDD8453+/8zvedc74f8B8Y8zTAuXNnjxeLlUy1quPQITf6+nzs0TePvHrxg8tbz0WamJ' +
                    '4KLqd/zDWbLbAsC4ZhwLKsE7csC5SyOH0qTD759Kr1j6Tl4n3mw0tfvLb9sJAjhIBSCkopCCEghDg40zRhmiZarRYCL/qHk1/Gai/0vp5rx8lB0sJuJbj9sJDjOA6iKEIURfA8D57n0T6EEAKO45y5pv15/s7qD1' +
                    '+vrf32qM3j1HQ9/lnP79s7OUEQIEmSQ0gpBcMwYJjHRbXHlFLwPA9RFFFUqpmvZmLHuzK1wTUIoRBFEYIgoF6vIxwOY3BwECsrK8jn81AUBW63GyMjI9B1HYZhgGVZsCyL/AP5/Ww2G3MyTc5ccds2IAgCbNvG7u' +
                    '4uNjc3kclkMDo6WolGo7BtG5IkIZFIYGhoCEtLS5BlGfV63bnzuRvXRCfTQOAl6Mb+ZcuyUCwWUSqVYFkWFEXB1taWNDU1hWw2i0gkgmAwiEgkgr29Pei6jmazCUEQwPM8Go3mt3fv3pMpABQVtW6aJsrlMnRd7/' +
                    'gey8vLWFxcRDwerwDA2NiYr1arOXFVVfE4sQBUVbsHgGEBoNFoQlVVGIbhlHLQ0+k0PB6PD4BvZ2enK65pGiqVCpot68nrM4wNTdOcRzrofr8fs7OzmJ+fhyzLSKVSXRhBEKDrOjhKnpD2+b3HKKWQJKnLk8kkCo' +
                    'UCUqkUpqenEQgEMDk52YXjOA79/d6TAEABIBwO/bp+P4eenp6OdhwfH8fAwACi0ShcLhdkWcbc3BwmJiawsbGB1dXVjvs/dvSN7502fZS/I7z97sS+1+sDx3EOKBQKwTAM5PP5js2hUAgAsL6+7qxRSnDz5jdMR+' +
                    '8nZ65wK7d/abhcrn8ld2+dOeF95+yFapegfPzRRY9a3asdFI9nsYWFhQ4e2iF5iet2PH71sFLSS+1ef5q98nL/8DPp6Xe3Frmf1nINy7L/lowQFrHY58xzK//t9C32wfYf4XJZy+jGPtwuEb29nuHIe+d/xv9tfw' +
                    'FATFKTqjXpOQAAAABJRU5ErkJggg==' +
                    '" />';

var updateGoodIcon = '<img src="' +
                    '' +
                    '8kuytRWzRUCqVYaggl2+oiphZTXKPtNknTpMnu/Llzx7MRH3Lh4zAP3++ee843DHSGhkuFqVr9BYbYA2N+QpM8x1R8XU94kqZT1b2krvkJRfF8HvkiijwWR35jaWmQNQFfnhkZO1SafjZmEiAxhFYSjZ6tMJgAEx' +
                    'ECHkDwEHJI4hHUiGPgGRPJxemDK4Avhr79vXCdPyboKwaDLMtofXoLJElCJGLUI4G7YYT7AYfwSVQ/zSsQ1V/eXgEcOX129psbzCEHdFmCSsp0b0TC0CHiGB4Blghwm4z1kANBhE+eUnG3MrafDRdL0m0pFZybjG' +
                    'S1ebMiQVNkuOsfgZm2/uuAzA/IPEO3/+OH8BshjvYYqJYvv9kE2FejzNzx6x6ycoyMocHUVeTW5JDrdNEg81w9wEw9xPSyjxsk7oX4cWcqrl678kYTsOFSmL15fIrBqS/DSahIkpxMCu1r22mAAvfJcK8RoEZ1iq' +
                    'qgemVHMvrr14nX2VDxq57vvNz4cE1H29IismS2mpBWA+lcBhIEnnMDLPgT8MI5xMwm2Gb0dYL/OVl5jRWKpZeH5t3R72cUaIGHtKIglVBgaCpSTht6n5jDscmjELRShYbLaaCm3IL3N+0V83/c6WWFQnHfpXup0+' +
                    'M1AZ/eu1Bv7lxAp430vdiB0fAIHB1IqYBKMelp34bnH34JBy4exscb+/rZ1yMj74Rh+FlM64qoYU3TEEsKtQuI9Q8wPn8WdsJBLDzYRgZv5T/Cqd9GcPXOOWzLvPozK5fLXRSFrUIINwiCbOD73Zzz3SRpYc0tCs' +
                    '9F9G4+hgu3ziCf245lruFUpR9dbRy28srsSpD+Pz+cP/+453mXVU11FVkB1i7i2uwAut092LmhfyVUAz/tgywmaB4m8g99UF4FKJWK76mKethqs5BOpeFkbZSqB+g5N7EltxeR1I3K3/30v4GG/CR2dR56dxVg8M' +
                    'SJdclk61jatnN22obR0gLZCnBh+kMKUgVcyFBYBDeZx/aOg6OMa7tXAZrn5OCgbVnWftM0dxiG8ShjTDOSiZqcWRTL4WyHqblVS2k/yUPxeVfHJv4vpD6OQ8IRFmYAAAAASUVORK5CYIIK' +
                    '" />';

var settingsBoxBackgroundImage = '<img src="' +
                    '' +
                    'A4eFBEUHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh7/wAARCABQAlgDASIAAhEBAxEB/8QAGgABAAMBAQEAAAAAAAAAAAAAAAECAwQFCP/EACYQAQEAAQQCAgEFAQEAA' +
                    'AAAAAABAgMREjEhUQRBEyIyM2FxI4H/xAAYAQEBAQEBAAAAAAAAAAAAAAAAAQIDBP/EACERAQADAAMBAAMAAwAAAAAAAAABAhEDEiExEyJRBDJB/9oADAMBAAIRAxEAPwD49Ae1yAAAAAAAAAAAAAAAAAAAAAAAA' +
                    'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABtjgpqY7ZLk5pqgL6c5ZbIKDa4TrZExl+l6ymwyG2WG2DLZJjF1AnY2BAnZfTx3y6IjRmNbjPStxWYmDVBbj56Wxx89JgzS3x056U1JJeMa6zm' +
                    'prITsnZlVRthjMsbdkZYf0vWcTWQmyxCKAvjiCo1y2x8bRHK+ouJrPa+ja+mm9/pMzs9LkGstqN+c+8Yi5Y36JrH9NYDe4SzeREwno6yaxF9SbZeIozPignY2BA10sZcmmWlPTUUmYSZxzDa6fqKfjqZJqg04U/H' +
                    'UyV1mNPxn47sZJrMX4Xc4goLcajYECdjYECdjZBAnZOyiotsmYgoL8f6TMZ6BmNeM9Q4z1Fw1kNpjPRcZ6Mk1iNeE9HCejJNZDbhPSOE9GSayGvCejjPRhrIa8Z6hxnow1kL3E4oaoLXEB0ybTyx1NuV2dGrZMK5' +
                    'L268vnjNf6NNCfrZpl2c6zktS6rN0cVfj+bW3F6ax2jXKfGOrNtNz9Or5HjTc7lyR63X4rsbLDk0iRroY/qrL7dHxJ26ccbaEt8TljEXB0XHwpeMvcd7Uc+zGYL44VeXD3GmHH6pXjgmzPHDZza0/XXftNt44tf+' +
                    'S/6ctcgrLC9rYwvZO3ldW/x8d5V88E/F2/Hd/bTLjt+6PXWkTWHK0zrkzwZ3B2XGXpS4e3K3EsWc0w6aY4+mvDz0mYleP1Zsw1Z5jK3y2+T4z/8YWuV/LY1X4tKbogmqlOM3yiq2n++EepPx1TAmLXGSrXF7enjl' +
                    'rh1p+r/AMZN/k/yMK8d/rrHwTEDKtNPPjenRhnhn4jklWxy2srrS+MzXXXcFfx+F8NSXT3v0zvyJv07z1+sRqZpT7LhL0rdffqM/wAuXe7E2pC5La6fgmn4Z46+W/ltNbC/a1mkpOwpdNHBtzws/dFLq4y7bLatf' +
                    '6RMsssFMsf6dEuF8TyjPFzmkf8AGtctx8mzXLFExcurWs+KZGmOF9L8Fih2Y8Ti24JmC9DsxkmxxbcDivRNZTGpmLaY+Di1FE7Mpim4tZicWvxp2Y8U7NbijinRdZ7Gy9xTMToms9kcWtxTMV6GseJxbcS4nQ1jx' +
                    'RcW0hYk0XWFiLGtitjE1XWVgvlPAxMLrG5W92otEM/VSRCYg6vizxXTJ4Y/C/bf9dN6e/ir+sOFp9cvy+o5a6vmX9OLktebm/2dKfCdAOOtrYur4e13jkjp+D/I7cM/tDN/jruOzg1f33/Xo5dPN1v35f69H+RGR' +
                    'Dnx+o3TjlYoSvJEy649D4130rbXFrXfPJ06GW3x65Mvt35bfpDFY9lCN0XsebXReZ5THaXwcqoi1ZtJjXHUyx6rXRzyyz2tmzmlOV+lryTCTD0ZtfEsW4zp52GpccpZ9O3T1ccsLd/L1U5a2cprjl+Tf+rG9ramX' +
                    'LO1R5Lzsu0fABnAWx8eZVU7nwb46+c8bt9LXl2l7cO7TQv/AEjtTltEszWFvlfyVk0+Rf8ApWTHJP7SsfEioxqrJiiYsSOjT/hzZ7r4fwZsq3afIZj7Jb5N0Toc9aTumXwqLovunK+YzN17SmNtG7akrrym7gxv9' +
                    'uv42Vyllu7vxWj4zaE3BEwbWIuLp0Y7M5imYo1c/wAfiRjdXL2kzWqxsuqYHFyzVz9urR1LnjvWqWrbxJiYOMOMYaudmdktZ877ZnkrE/DrMuyYwskm7lx1MvdXxzuUylv0sckSTXDU1N5+mqTLL2omduM2mW8dG' +
                    'lbZd1+Knxeq6ZJs9NK7VztPrHicfLW7MtTKSyRZiISPU8TZGGe/aurldvCTMZqxCbtv5GNvk3vtz7tdWmW3atyitt6UvbNrri1yitpelXOZ1rE5dCttGZkY1AMNCYgB2/Eu2mvl8jCSz7c3x89pYzyvmu/5ZrWMY' +
                    '67K+tq3OzdkIcJmbTstxGACYJlb/Fy21Iwi0ysrVbZOkxr08dTGy7Xpwat/Xf8AVZnlOrsrb48unJzd4ZrXEXtMqOxxabaerxwuN6rLKoFm0yYIvZe0JgAKAACZbOqgBKAAAAAASgBKAAAATECYN8b/AMcmN7WmW' +
                    '2lZ7qi2n4QAMAAAAaLYur4d23cuLo+PdpXbin2GbfHZKi1TG+Oy5X6evs5Yz+X1HM3+Rd9mFebln9nWseJ3baOrxxuLCdJlZreazqzGrZZb23dW9oEmdVadL6X2yaafV/xqEmEJnatTOiBvoZzHfetpq4+3HKnd1' +
                    'ryTWMYmuuvPOceUrnuW93Rb+mRE6LXmSIxblYtllymzP7WTsYAMqi9q3tdFBVFW+kXpFhT6C9jK6//Z' +
                    '" />';

var pausedMessageImage = '<img src="' +
                    '' +
                    'I8QYUwrSGbtAnJETWEwTVEyWQCRGMSgyK7oiBi3Gh6ofd+3f2Wfsu9t77549V9r+59972GYDLnIHVOnV5q+9VXv6/qV1W/ugLHw7CB5EIAVQAqAAQA2ABiAPoAdAohnjuO0vHgozezAIwHUANgJIAgAAvAEICoEO' +
                    'KHokjhs1WhcgClSvEEAAnABJAAEBdC7PyYhD1XKXiZEhRK2KRq5/WjrP881Z8RAEKqjQAAQ0Wh/R5UfS5XZSrVzzKVbioC9gJoB9AqhHjhGFemswCMUmMUAlCi4afrkVQTlKnGbkgI8donkHz/AuAEABMAjFXYBQ' +
                    'EQQApAHEA8WKDwNABjAIxWBR1SCAVuWlUwSPKfhBCvHqWwFwGoVqtMuRpcqEEcUu1c9NcOJMmLtf44RCpVfTI8MaBiqco3Qsk0Qv0Pqv9l6ncHzGNZmaaoWXyMmozKNRI6uEEpl0PAlJqkoyRnCCF+9wnjYLXCa6' +
                    'xGwFJtYUkBSAYLFB4LYJwCvUopnwO2A24MQL9KO9rgzBKj1QyrK3ocwMBRtuPUryuQTsCAh4RBbRUMqVgKIc7xaOZaTdGO5VCl8KtTGI7SJrGARkAo/bDU2A0BiADoJ3mdEGLtJ4iAtSqOhRDXefTmTYWRlUdA0z' +
                    'Q/b9t2bSAQGAegFnPmfA7PPvtpV6avfGU/nnxyq2PSkbxJCLH6KIQ9UZF9NIRY4BF2pRrw8qOsfyyAaghxa8FcZWUSNTVpTJ0ax2239eGKK5KKiI655Q1jlKKZx7gyVaoZvRZC3F8wVyhko6YmhbPOGsAttxzANd' +
                    'e0AogqAleSvFUI8fgnhIDjFQHHFFgdJQCZtwe0LOtaIcSJhmFMkKnUOGPChC8hHC5zZaqpSaGj408oKRkAEAYQFkIsITlfKaRU5og3CJ89VqVa+aoBjIIQV3sI+L9qEPvVShhRM2tazbZ6W0Jb0Zz6q1TdGRNXiC' +
                    'sOG8Jbb43iscci2VleiDqPbLvUQUw3gB6FRUztfSwlHzX5+LewED2/UzMFKYR4juSXtb2aE+kxGbNmkdq37dJM0H9X+5mJEOLOw5Zszpw2PP30HjVmg9r4xVRbJgDbtm3pKKRt2zIUCv3KsqxZgUBA+Mit69Jfg4' +
                    '+zT3WiLYT4H9XPf/Oxhrx1OXhJIcSvVblrlUVQofS5RlmQdQBqIMR5Hr3pceRwdaKnp+eKMWPGTAQwyTCMCXjiiTPx1a+e59utX/7yPVx33SEN3JgyxcwiBNT3WSXKrKxQK2lmlRPiAo+w25xTI9VGXGvHIaC3DX' +
                    '0PV6HqHgVgJIQ431N/CwADpimweXMIN95YjdbW3Gr36KNxzJ9vZYZcVHnKvqf6P6BiVMmX9iHg35KE8NQvPT+FjxLrSuiYjAnVh4gi4StKwW5SVsSJEGKeB4OPFH4GXn01hBtvHIu2tpxl1djYhLvuala4OPgMKQ' +
                    'JaUkrbMAxbSqnLQ8MwIKU0DMMQzs8jJF4hjLwTj65D+hmA4dOWi4AatiVqm+Ic2jmT/mg16Z/uwSziO4tYljVLCHGyQ0B+8YsXiZdeGgsAmDTJhBACBw9mwL3yyijWr29SYDqkcBSvGAGFRkD9oKMMQAhCnOER9i' +
                    '/azJxQP3UFL0TAoM9BSghC/IOn/l4X2Bs3luDKK0dm0889V2LXrqQiYLmnbJtzGqxhkNQmh/8vAurk060D4aNIlnZiGVOTaRjAoBBigyLgAgCTFAHneDBo107IgfXrS3DVVdXZ9MmTk3jrrQ8945dyxlBm2OWMo5' +
                    'RS0iEgACGlzK6Azv8+RnxsjfTeBaIYAaUPaUMaCR0iVqhFZaIHs+yZQdDH1q8CUMWOjjHYtKkmm3LDDSkIIdDQkCnz0ksj0dtbjbFjy1Rj6aziCXGhp8HNWQUQ4rOetP0ASiDEab6w5RNyT7ad7dvL8NBD47FjRy' +
                    'W6u0Mggbq6NC64IIq77+7GtGmWRvRS7XTVtXNxAX3ppW7Q333XKLD/gyJ2ZrXdvr0aTz5Zji1bynHgQBnicQMjRkjU1ydw2WX9WLy4DRMmmACIyZOnYO/e3Go6b14rVq06kP170aKJWLbslOzfZ5wRxbvv7na1vH' +
                    'fvCPzwh/XYsmU0OjvLYFkCtbUpXHJJGEuWtOD00xMeAgJCfM6D5Xo0NNTjiSdOQmtrJdLpAKS8TxEkpeUManthb9CvqAQuv9yd+sEHIQCV2L59NJ5+egQ2bx6BAwdCDj6Gg8/997egvj5lGAZJOqavMAKByz0yv6' +
                    'L155KCaQDws5/VYc2a8Xj//ZGIxYIIhWycdNIQLrxwAHPnduLiiyO+W5g9e8rxox+diC1bqn2wbVbYugmYTpdg8eIT8cwzdejqKkV9vYVbb03gnnv8zgcCeeS2LGumbdsLbdteIaX8DR944AABEiANg2xqGmBTU4' +
                    'SGwez/GxujJNtJtpBsIvkhyfez6U4k31XxLz5pbSQ78v5fKJIHSX7ExsYuBoOyYL5gUPLhh3uz9ZM9JMM+9cVdMRYbcqVXVJBkimTKp2yEZJhk97Byjxtn8sCBD0i+w7VrW1xpEyakSb6TjRdfHHWlNza2u9JXrm' +
                    'xjKFS47yNHWtyw4QDJvST3ZKM33+zZ7T59WkLya2pf4xDhTpIPkXzeJ3+Y5CDJKMkoYzG37OXlkmTPsPjU1aX50Ud/kVK+reTeK6V826e9HA7F0u6/v/MwdGkPybdc8ZFHWg4D2480XPeSfIdXXx3xzT9vXtqnXd' +
                    'OJOgHn2rb9Hdu2/1tK+Qd55plxp4C85BJTKVuMl15qZSs6+2yLZD/JPpLdJDvzyCSEQ7JDJA/5CNOn6oiQjPqkx1TagBrsHm7aFHZNBJ/+dJpNTV1sbu7iWWelXRPHq68OqrIZ+fPrH1IxQ8CNGxOu9HPPtUkmSS' +
                    'YLlM3IN326yeeei7Cjo5em2cW2ti4uWOBu74YbYiTbaNttPOMM98Bs3txNso2JxCGWlUltwCUHB9tItpJs5datXQwEcuXq6y3u3t3Jzs5DPP/8nIxVVTZbW9tINqtJ66CvMv3kJ/vZ2/sCySdJNpL8Nsmb1YGEQ8' +
                    'A7FAHX+WAwkB07MpaH3znnWCQHOH26yeefj7Kjo28YfFpcMV+XWrMxX5Zc2vjxlitt3boeJpNtbG09xFWrejltWtKFDXmQW7a0+2Dbwc7OtiLYtvCpp/pcbU2ebLG5Ocrm5jinTLF95LScmLu8se07bdtulFKuk9' +
                    'u3v+kqsHp1XCnaENescSvO3r1DagAcRe93pQcCDsnCBVagqFL+IZIJn/SERpAoyQivusotw4YN0Wz9Gza4SXz11aaSPdOG/woYo2lG+MorMU6a5AbssceSRcomlXxxbaLI4TA0NODKP3GinZVz9Wq38t1xR4JkmC' +
                    '++GPHMoEmSvdk4c6Z7JV61KppN27TJ3d5ddw2piTEzOXrlf/jhJinln0mus237UZL/Zdv27SRnkfyCRsD/IPmjIivgAE1zkK+8Ei+AX0SLOj79Pvj0uGK+LuWwyJcll1ZS4k5bvjzGffv6mU73etrozsaZM5NHiG' +
                    '0PyV5On+7Wx40bHX1N8He/Sw9LQMuybjZNc6llWaullL+Xt9zSlc08apRkLBbJEjAWS7CyUhfE1BQwlreKZUCLFFnhcuTzX2WSmqJnOlZb6zYRwuFY1gQKh2Me00Zqq1zisE1dgJw/f4i23ZtdoYvJ9tprSc6ebf' +
                    'LUUyXLyzOztTd/SQmzOJlmjCedJDXlk7TtGL/5TfeA7dwZ1xR3kHV17r63tubS4vFBV9qZZ9pZZSf78uTp7HyD5Au2ba+xbft7ytS8luR0jyfMbSR/QPJXR4TfbbcladsDJAe5eXOcs2ebPOUUexh8BqWUg1LKTJ' +
                    '8K61KkwJYgE88+2/KVKRQiL7rI5Jo1cYVNLh45tpm0MWO8+pjI6nM47Ld1STsx40uVSt1rWdZPpZTrZDK5WdbUmIcNcl2dZDqt76NiPqBFsyZKYQIWWwETLlMxGHTnsayYS7HzBzUnX7G+hEKSEyemOXPmIDdubF' +
                    'V72ma1z+0paL4+80zKZRIX33fkBmfFCtNjhqY4eXJuBZk61c5Oao5iefteLGb2X4NZ8z1fllellM/btv1j27a/WcQV7WaS3yX57LD4nXCCyS99KcYXX+zJ7r2ffjp2BPhECpLMrUvRAtZUJm7bFue4cbJoW0uXul' +
                    'fnI8c2s6joZmtGH3OLimkmik3cwaGhoQYhRJWUcgyAkWLt2nFGX1/wsA93u7sFNm4UmDnT8k2XMncEHIn45bCHOVq2847vq6uJnp5cmWiUGD2a6nd3XdXV9K0jp13NmjtZUrvHNDRXtBGa76fr7AqAwNKlIdVP5+' +
                    '4rhQULLJSUAMFghY8zQibefDPR0AB0dzundkHs3WtojgCm50ohv+/FwtCQ8Byd5+UQQkRI9kcike4iNZla9OL3gXad4VxBBVynz9/5zmgPPgksWGAqfCqLXJwX0yVR9NL9M5+x8dFHcfz2twFs2RLAe+8Z2L49gF' +
                    'gsV27lyhIsXpwsqFeHhy1RVUWEw159lOp3owCeAEAjGAzWGoYxxjCMUQDKxFNP1bqyvvxyD8gOkJ0gu0B2o6mpD4ZW7y9+EdCuIUyEQvoAAYODmbumN97wU4K0duyddtWbAT3tqhtIY9o0tyJs3cps2tat7jYyeV' +
                    'M+R+tOiChvli4AhwC0AGhWP9uUl0tY3Y95Q6bOAwfcQs+fn0BZmYn9+2XRy+ARI4A777Q15wYD6ggeI0cS11/v3Jelszidf37ac8zfD7JPi2EVM3/ruOWvbHEpZRTAQHV19ROHQcBC+PUrnDqQeR3SrvAMA4igqS' +
                    'ngwSeOsrI09u+3C+hDLpaW0qVLAwNmEV0yXbGiIo3ZsxP46U9j+MMfBrF//wDcnieGK//555vDYKvH3qyMU6Z49VFm07Zt8+tj9k7U0JyTS9DeXoo//zl3P3XyyWlcdtmAuqCNKU+GKE46aRAXX5xzQH7xxRJ0d6' +
                    'fUpfwQTjnFLdDPfy7Q15fC/feH/OYSLcZRW+sW+I9/tD15Eli4cBBCm6gWLQqhuTmN1tY07r03t1IZBrBwYb/mLOD3aiGslOcQgIMAPgTwgfp5UJGwSymZv+zjxrllXrsWCIfTWLiwtMCKnrskv/12icrK/FzXXp' +
                    'vGqFEJ7aI/Mwbf+EbY1fc5c8qxa5cJ00wgEkli504Ty5YZmDx5lAe3ofwrVhE1DCNiGEZkmPne1JwhvKFfw69ZYdas/s6QsLbW9HhRAeFwEgsX+jnYJ1zx1FPdltWqVQb6+pIFdClX7rzzRmLFCgP79plIJBKIx5' +
                    'N44QX36lpfb2l6Ec/D9vrrK7Brl6Vha2HZsoDCNtfWTTdFXfUuWhRCS0sKLS0pLFrkJ2c8O6aWZT1rWdY6KeUGed9977ls1W9/u5XkTpI7SG5XcQfJXXz88SZX3gcf7CC5j+Q7bGxs97Wbb7jBbx/ytop7Sb7N+f' +
                    'N7iuwPcvc83/9+OwOBwjZ+ICD5gx8c0u7C3iL5pk+dz5F8hOTSAvufpSr9uQL3SG/zgQf87zFnzYoUODWMZE/JyCS/9a38A4MdO7rUHnQfyd0kd6mxeJ3LlrUU7XuurX0K2z0kd/uk/5jkt9TDURTZA/4rydtJLv' +
                    'Op4xmFz3c9ZR4kuZLkc7z33nd95bvmmv4C+rA3G5cvbzsCXSp8R+iNhkE+8khL3j3g977XdpjYuuWcMWPAN9+cOX5yvknyDZKvC8uyHhdClAAoFaeeOkM0NVVljFODeP/9l8UppyQ0typnDxPE0FApxo+/HNFoxj' +
                    'vitNNieP/917P7uSVL6rFqVT26uspQV5fEjTe2o6GhDYGA13vhZZftnkgEcM89k7BhQx3a20cglTK0vO53h1u2VGD58nps316F3t5Q1lF82rRB3H13Ky66KOrxdCCE+IKn/RXKkbpLCPGYj/LNz3q2C/GfnsQ/Zd' +
                    '2XGhrq8eijmf6OHZvGl7/cg4ce6kAo5HXE7UDuKVTG5enllwOYPj2kuW+l8dZbBzTLY0itQsy62W3dOhrLl5+InTur0d0dgmUZqKw0cfLJQ7jggkHMmdODCy+Mudyu8vu+FIfxoJjk5wDUA/gUhFjmSWxUq2CvEO' +
                    'IR/eQ0+xwHqMZ9952F1atPQ3d3OWpqUrjmmk40Nh5EKHRpUX0ABJYsOQGrVk08DF3K6ce2bRV45pmx2Lq1Ck1NFRgcDCIQIGpq0pgyJYI77mjFjBn9vp4wW7dWorFxInbsGO2L7ezZ3fjsZ6MuOVMpA4sWTcKzz3' +
                    '4KPT0hjBuXwty5HWhoaEUw6JXz9w6nhG3bDdqGuUQphqH87qicZU21waZSuBItBop4rB+pz6LQXjTodR2p57ufQ7Ke5jwqHlJ7ux4A3UKI9X6zv/Jqr0XusxTeF/XCR/aAdhih+whWaIc6mToaGkJYvDhHwIcf7s' +
                    'DXv96szON+tc9KKdmDRbD3YkXPIYzudB1R9Xch81mN14oQ8ALl3V+rHIzLkfs0R1zJ2CeE+I1W5krkHqM6D6GLvaTH30AfhtM7qfnrQhs3w6fNQvrlJ+fhjIMNwAqSbBZClBiGUSKlLDEMQ39gKQ3DcAbNFEI8qh' +
                    'xz8wj7VxLQz2vfGKYzR1K39HEMd9IcB2TnqVNfoXNeBVZSkXWE5v8Y8Hlp4P20hXOK6vjZjgZgQ0oiHC7Dpk0BrFhRoj31sjBvXpt2MNQlhFiklPprmpN56REQUHc+dvod10g4OAyuUTXWUk1azqc5LEVm56mRvr' +
                    '/cQPLzKv+AZ+IyChDw49aHj+M1RLFJYjg5UcAB3BkHUwCAaZr/rMzQIIBAIBAQtm0jEAhkveV1E0V976K0yCyMAkIM925tls+MdzhvwIrVLYUQz5O8xpPHedk/BCAmhNhdZAWYityj4GKrn5eEQaWsI+E8aHUeae' +
                    '7ZU4spU07Na2zVqg8xb94HADrVQcYhIcRKTZYZw6yAxZTO1lZ/51MaUSHE28NqLvmPyH1TR/86gvPNnjcLlLsQuW/9lBaR+ePUh2LXGnlk8HkPOJyMRyqn3wpoCSHWH83bquPhSKdfsgHApwCMw+7dE3DOOVMz7z' +
                    'FCxOmnJ3D33a2YO/egdqrYou+rjodjLwSPQ/B3De3ZmXLqVAlyALnv3zgfoMruy9TP4+E4AY+Hjyl0aearrfZPpYqUzgeowtre79fHITu2w3ET9O9vhs5RZqj3U3UOAfsU+dYcR+vYD/8HshtVUk4+/YMAAAAASU' +
                    'VORK5CYII=' +
                    '" />';

var experienceIcon = '<img src="' +
                    '' +
                    'PE8Ifm/wBgeBZ+lYbn/wAvOyhSXAC/7wBfdwCPsyU6QFOSogAiKinU/wDG+ABbcgAGCCTT/wTO/wGbwkDZ/3nk/wDC8gMFBV/h/znY/wARFjHV/16Pmyx2iAAKDAAKDQBJWwAICgBmfxU4QAEDBEfK6gCiywA7SQ' +
                    'BngRFEUQ3P/yXE6SE8QgB0kgOjyy7X/xjR/yg7QB0uMhxCSxU9RxtvhAI6SA7Q/3nM4QBuigB6mRc4QAo3QQBiewA0QQKfx0nb/wB3lQUSFQBlfwGgyAONsAACAwCWvSk7QAAqNRrR/QTB8RvO+1Pc/wIJCwjQ/x' +
                    'rL+AA8SwidwgCFqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAHIALAAAAAAQABAAAAeagHKCg3INGYSIiCQ7iY1yKUNCjoQ1VhZUk4NQIl5jiWBRSihPZjozD25HWUFaRQ' +
                    'QHUzI2Bh8GazkvTRMeXRUFgiNMajcOK05IG2UgKogFSywXVTAlJwg4jnBtNB1EWFyObElpcVcYFGE8jVJoHAEMPkZfGo0hMQECcgILQCYAiGRiEvQY9ONNCwiIJGxxkehMBH+DFAxwRGBiIAA7Cg==' +
                    '" />';

var badIcon = '<img src="' +
                    '' +
                    'VaDaIkD5XapIJIQl+KNj4ktFm7ZrOX7H1mNzszOzM9O9G09j8cGGbO9zvn+18I/hfhUMjLctxBXhC2EV33GoYBg5BQaXV1WlXksc7NvtB/95NnL08eP2ZYhhnlCtLxJ1cucisz9yGnk+Y/oX4DGnt64dmzVy1yws' +
                    'myrg9v8vm0dcBSOMzwPD8u3bm9e+HcaVid9WAF6zrdoKssl1DKpNF19CNwW1+/qShKfwVi7kksLweKUz/7F8+fQbWrCbzNDr0g/QugBIvNBkUSUUjE0fn+hyA9vcGOrq4hEo1EvNaCNP9g3yBnc7vhenMH3O/ux9' +
                    '8jn0NZ/GvNwgub0P7lV4hcuoDknduQYjG8dOGyKrKcj6SSyUD67Hf+/G+zqKpvQNf578E6alEW84gOD4EQguYTATB2O7WQwdyh/SBFCY5Xu1H13pEgEfP5mfDAO91cTTU1SlDV2UkFQSpwQKMQQh8LFcvZLB4e+w' +
                    'C1mRTA0K2FIlwXx2eJmM3Gwm+91uTwbYQmGdCTUTDtLWg59yO9SZ1poSJ+cHgPGmPLsDQ0w1JDIC4swT0xFScSBSxRQM2LHmjpRWh5CcLmLXB/ew3MU4CSyyL+ySDUhYf0mx2M0wtpPgLX5DQFSNJMvO/tbsYiQp' +
                    'ejsG55Ga7R62BsTvNkmgLwtXXUTgaxLwag/DEHi9AMTbej7vKNWZLNZALymW/84sQlMM02tF65T0+pN8Vzn/ajpVGD67MbNCdOlHNp/DnQCzYhwr5rH4xDR4NkJZHwVou5+ejgGxwsMux9e+E46MfcMeo5/7tpgW' +
                    '17BU0nruHR6a9hnfwBLHi4rv6k5nirz+yVbCoVwK8T/pUALRtnYJVeuUbP0O552kk6TSTrBEnmwNAGbhgKQO7eHnS3tg6tdWI8xgiCMG7cvbU7dWoEel41QZVymUFFhkrLaeOw4eMRqD07bpbkUn9re4e2PkwVCM' +
                    '9xo7yUOl6cHOOK935BORZZs+D2oHrrdlh3HlCLguOkopaHN7a1ac9N47NI0pxUxpmubdDK3sogGBYmRIdnWpXlMbfH89w4/wNi4WxKCJsyDQAAAABJRU5ErkJgggo=' +
                    '" />';

var pauseIcon = '<img src="' +
                    '' +
                    'J4SbRyL1ZYytLSLe1eW2cHIeqXTHY3O3PmnO87h8N/tbS0JBGedAmi0E4/pVwuB7oWNE0bNgzjTm1t7cLf+7mdl0gk4uZ5vhcu982pr2EyH4kilU6zf778fEjBChw9HDItQ79tWVZPKBSydwF+Li+7BUEciMjrHW' +
                    '8mp1FY4IMoCHC5XPRvDtlsDpquI5nawolj9Sj1+wYpm04HhAHIstz3az3RPfn5G4oCfhBCwLvdFGCboANg2RYMw4QST6DpyGEEvGK/JEm3uJWVFYkXxPCzkXekOBCAKAoQCA+epwCc6w9AFqZlwzBN6LqB2EYcZ9' +
                    'sazcxWqo5TFKVvPrrWrSRUFHjzKQDB95k5/FqV0dLYwFROfJhGWUkxDh0MUSkG1K00ivwFqAj4+jk1qY59mlls9eZ5qFq6neMwOvEeM3MLOHf6FGvSi+ER1FRXoa21GX+mgnRGw6Fg2Tinqurql9lIaclePzKajg' +
                    'xt1tvRcczOzePC+bOMwdPnL3FAqsbJtuPwiCLyqMzYRgJ1wTKZAqRWvy9GSwN7fKxZDr1Xr4cRDv/AlcsdrAcPBodQR+mfOd3OZDos45sqaipKZC6VSo3NLMutHoGwrgt0Ao8eP8HUx2ncuH6NAdy9dx+NDfW4dP' +
                    'ECdDqJLJXgPIMl/nEukUj0Kcl0d5LeLNLDzgTGJyaZhKuXL7G+DDwcQm1NDVqam9gkDNNiTLw8+rlYLCaJnrxweClKHABCAQj1gNtZru0x2nSMlm2DOhAGXbphIVRVZqrJzTrmlHg83qdZ2e6orGx7gAG4mNYdI+' +
                    '2AOAz27ysCZ5v95eXlt9iONVl2ix7PQMawOqJrCrOwc/suQC7HzGTbWXbYDXtQ17TOqmDQ3g2TA0IEoZcnwk1lUyWb6hZzn1OEunKPz4tAodfUM5nbhmn0VFZW2v+kcaecntAsdNFk7saZ1gIND4szpf1PnH8DjE' +
                    'h/b2bB2sAAAAAASUVORK5CYIIK' +
                    '" />';

var defenseIcon = '<img src="' +
                    '' +
                    '9dj9Pi/jFShI6hxHef6G2Nx0VdiDlLaePs/rrR/SxEaaWwxYCh4lWH1198slqJ1mN5oqLA93uSv05ihUJkm0JusF+IyzRdm22b6DdfnGWV5HSg7YKq9Hul8Iiv+K/J/M3e/v///yH5BAEAAD8ALAAAAAANAA0AAA' +
                    'Z4wJTp4ysaiwRMaHPqOZ9OlcZC4PCu2OuoA3txdOAwmMJycQy7tHonkkhiBkNuTs/hAKRSIDCx+f0TNAAVDjiGh4YKAAMFPx4tCwqSCgsZAzI/Pw8HDSsInw0REQmZPygzAgcXAhAQDKWZCTezswwOsJkPDDUgja' +
                    'VBADsK' +
                    '" />';

var staminaIcon = '<img src="' +
                    '' +
                    'GFi6qurmVjYm1jZGhpapOLjHRoa1EpLnJvdt9KUeyQoZ+foLKJkeBpfE5QUO/w8FRJTOJTXpSVmudVZNHR0sdkb91wfICAgIR0d7t3g2VeZamnq7NWXPJugGRWXH9BR4BfXAAAACH5BAEAAD8ALAAAAAAQABAAAA' +
                    'aJwJ9wSCwaj0OJUFBTiByBQIohWAxSFeEA8SFUWjJExOKBRSZCBYlAGBU6HQvFQclFhJtXiMVAaDQmA0UDADsJAiA8LjgBCkUJJzE+IgsiCgMTSkMDNAYABJcDCgQOmkI2KwYNggsCLI5FGQ8oKrCmRTcPGAe3Rw' +
                    '0XM7xIQyU9HDrDQxDLvcnOQkEAOwo=' +
                    '" />';

var huhIcon = '<img src="' +
                    '' +
                    '843IaOTM3mNCE4fCaii84QTKAWJrTYUqBl13tv7707PUaHO8lJzuv3Ob/vL78vwf9GIBB0CgK/WZIkt2GaTtMECMyALMu9qqodLSsrCcx/T54sgsGgheP4PQkZLce7B4TL1wOYmkqwuwULMlFX68LbTdWayCf3G7' +
                    'reWl5eqj8FjI6OWURR7P7tj/uew50XYaMBQpoA88kvdKEpGqan5rDj3XqsqM3vUVXVm4IwwPhEqO3cpVHfoWP9yLFbsajAhuY1VSh15MDCEYwEo+jquYl7oRlEwjP4YOOrqK95ob20xOUnDx6MO+MKN9T43gkhJy' +
                    '8bz2dn4MSnjbBlpT1TG01LYlNLN4YTjxCdmMbJQ15NIko5iUQibZ8fv+XrvRUEny6huaES76+tZkF7v+lFPEPCvg11bP9913Uc7L8HXVbhrnZgh6einczOzl6t9f26LEPiAVXFYpp+cUE2JN6Cb3++iXc8L6NjfS' +
                    '0DfHXkIr67Mw5IImQlib5P3NdIbGY25Np52u502WFMz+Dv6BwicxpAtfs9VdjrrQEhBAN/jsF74AKstEaczYrAcAiDXzSEHwM+PGMvcuVh+OE/iEenAV1HXUUe+v2vs+BzfUN4q/MK4oKArFwrinMzERyZwGAHBS' +
                    'QSias1rb8viwtpmEiogIVKod3TvHQhWt+oYKmv/OgXjGRksqyQ1JGfJSJLlXHZt4JKiMXafCfv+joHQjAIRwEWNpeX5uIVh5UBjp0fwiRHzw2DZceZBrbU2OFfXdxOJicfOqMKGar67IKg8gL9hT7kOHQ0LsGulS' +
                    'UMULXlR9wW0x8DDB2ipmFgt1t7jjwqZ40UnYq1/XAj5Nv2022AVh80k49XlWHra04GaNh1GoO8RKVRAO2Hr9e9hLVLstsLFxX4GSAcDltESeruuhH27Dx1B6qRchCZZxWT1UWk24NNL6Kp0tajKIq3qMihPzVTCs' +
                    'IL4p5J2Wz5su++cPavEMZiMrsrtKXjzUo7ttcXaTZe35/U1FaHo/A/M80fqZqk7CwIglvTTabBQswAtXKvoqpHFxbkP2PnfwFXFV5DkrUSVwAAAABJRU5ErkJgggo=' +
                    '" />';

var updateBadIcon = '<img src="' +
                    '' +
                    'Z3a2yUukR/haYlaYtrNVTSC0HXxbCXpJt2L3M949mIP/LBy8vAvM855/s+AlapkWx6rtTsJfBNEGIFJM6MaIIlywGTk2TmsqnKkhUQBNNyPYt6nkl8z2rV68OkDTh0fHTq3WzxAZ9wAEfg6CpaPZuhEApCPdiuDe' +
                    'o64B0m14Poufhoiwb1RvHNZcA3qbEr6YvuHZR9+SDgeR7B++4Gx3HwqI+mR1F2PNRsF9RiYv7ZvQJo4fc9y4Avjn1fPXmZRFgCMs9BZIp234mAIoP6PkwGqDPAPAs2HRewPRzYJKI8MzVIRjJZbp4L2T/MerzYPl' +
                    'ngIAk8YrffCs3Q/7sBC99k4Qo7/R/LgdVy8FWPgkJ+cqANCF/woguHL5qI8z6iigRNFpHoSiCxOoYWCy80bVSaDooNC5eZXNPB6cdCfuHXsy+1AesnnPjVw3MEkWYDkYAIlSkSDSG5JskaSFFjgcWWjRLzOeaU+d' +
                    'k+1fv70i8vkFTmRM8pM3FupCSjo34DcRbW25CgAiMRBQeKRwwLG66cQXCpjLIWw8+xe7BrDXH/mp15jqQz2W2p67HcjxUBkm3CEASEAgIUSUQo0oGh6DyErz8GRyk41lzKGupLEjpfeZ3OVipPk3Q6s3tiMXTsXI' +
                    'nCYu9darZnTiGziQw8mMRDx99H8vEnlgFL4zmEt+9Aq1ZD9cxp6K/uHSLfjY6+5jjO5z4bl8cuLDG6zwlgz8T9jQr8sTQi255E58uDaJyfRrBnC65+sh/e9CSkHTt/I/l8fh1bhc2U0pht23Hbsrpd1+1n4u669g' +
                    'f86Rzc4p/o/PAg1K19KOdGUT/wFsTVa+H19leXF+n/+ml8fINpmpOiJMYEXsDGagnOoX3o2P0sjOeHUJ04iejDT6H65RDq344hMPBOfgUgm828LQrifr1DhxEykDBCsAafgdK7FTfZNIQLKQQffRGLhRrkSzOQ3/' +
                    't07wrA8JEja1U1OGWEw4mwEYayahUijetofLAHznwR4NlPbJPFrnUIvrEvZyta/wpAu44OD4d1XR/UNK1PUZTbCCGSKgml5MI16i9UbuGj8QK6Nh51PP9gvHuT+y+285cc/rnNdQAAAABJRU5ErkJgggo=' +
                    '" />';

var processIcon = '<img src="' +
                    '' +
                    'aSZcHIDGNCXIjRoWFKYjrBNoyW6Uqh7b3Yfdkv6Mf13RINBjnJ++PkPec55zznOQgeYoPHjzkZhjHlcjlf58FX5x8Wh+53RoY+30aSVJei5Ns1Wu14SWlpc8DvfyORSJzZYNhwKJ6I97zQ2hb+X4B33n6rwPV0c2' +
                    'izzSae+3qyWxTFequ1rGFu7loPRdNVDE27s9nsd7v3uHY9ADB4bKBJpWI9Gq2mbe8z7sOyJClrf3lFgbvptBJbjEEmk1XuyFJNKpnMEASZf7619dd1gP6PjphqduzwcxwPweDCdG3tThduFTL3MoAIjI+h1nzMRU' +
                    'aW5EmSJPYmk0lPNBKpfrljv4I+7Our2FKxZczuqLKp1WqQZRlEUQs3AjckRVH8hQZDFUWS/BpINBoFgiDgr5XVc6HQzbau115fRgP9R0VB0NBGk2nCbrfXkBQFsx7P+UQi3vJsy770xUs/WAp1+kscz5XeXpZASW' +
                    'UvRhflAyvR2K2O9v1xNH76yyWj0Sjq9YXAcRyw+F29csXR0Ng4uzbj996Z7rPhmb6pm5fprJIHhqCgqaQa6tCmKddTuxvR2YkzS7hNTLoIQoEAPB7j+tw1xxO1O2d/CvyyZ8D/1WQwEUICA0BjSgx8EVQUVoJPDu' +
                    'SfM9btQp8MHhdxIl1WXjZhNJpqdHo95kE6n7ybbIlwsQsnAiO1Fp4FgaaAxtUPVvbArfgSvHv5feh89KVv0MnhoQpzcfGYimVtLMuCxVICeOcQjoQlH/pZH0l9Sz9u6YTphdPgND8JjqIGeG/mTShRx8DINEloZG' +
                    'jIhKv7EVqXxLTZXOyiMQDCbP+WnobfV4bBtfEIiKwVCmgtDHsH4M7KKeAZFh4ROhfWs8ZGR5vwnj2CRmgrMpsP8xyviDoR5fkMnPS6QUUqsG/zCUjmNPDFVTdwVA4yigbc5Z9+9q+UP+jtLXBu3x4iSEKMhMPdOp' +
                    '2ufpuzusG3egF+DPUCgQgAwooFdR1Hs1BXeuhPPVHueOCYsO67UqlUOz6e8Uq7vfmP4PyocRNnD6xO2ZbTIdCxZbBRW++hFPWLj5m3ev8DcL993H/USVGUSaVifK90HJiXF29vRYiwZHP3gkUGq/efuL8BeLNcQJ' +
                    'E3FaMAAAAASUVORK5CYIIK' +
                    '" />';

var energypackIcon = '<img src="' +
                    '' +
                    '2PTQwIAufEV3JbErF8AOW9N49hIfTBG/bZeNvEiubTl/TEJvzsu/DLUtW9cKVyAaJ3MLiEAtq5VfXcjcZ4MbyJAOKtAdmlAO65Dd2oAPn4+PXLP/K/FSUUAO2+ItaiAPLu6+u2CXRoP+PJeOfJZvzwysqVAO/JS6' +
                    'NuBEUdAP745v39/f778LWAAOvm4at2APDFQfG8EOaxBMSRAPXy8O9fAKRyDjcyIbSBC////++kALOEGtvMt+izBuK2MOXbt+3iyZ5uG/n39t+tDPHPX+3ALfCjDLOlduvGTcCNAPbhnMueD1hKHd3AZNVNAMKFI+' +
                    'OyD++6AOXPhr+njN3SybiGDO/IAI1gAP734fC+Gs+gH6J8AO+sAOPATevSf+Pa0uG0IQAAACH5BAEAAH8ALAAAAAAYABgAAAf/gH+Cg38fVUBlKHATQFUfhJCDHxURFkqXFkgEC2tqj5GCFAgWFpsYAzkmC0NDBx' +
                    'AUoFUCSUMrbjc9uTU1F2sofH6whBQCSjE8NTNNEszNLTMsQls7kghKB3c3SxFX3d7eJ0FOeZ8VBAQDP0Qu3Q5T71NsOBEvCSZpAIVdFgw6NEtxrshwQPAdDikkXoQxwaWFITsEcthoIEFKkgABHGTEkeSIgRc3Vp' +
                    'gRsQOInQUpoMyYkEQGB4wBuiWZ6aXHGDEiAHiwYOJJjRZyrmTgQPQlxita5tS4w2BJgT0WMEyEcKVNhqtDiV5BYIQIFB0YRCgYYYfBxBNXcKhNgPVKHCMN7KA8KVHESAEIBA7woEFEQoEkOLBgIZNkQpMGW57oSM' +
                    'GlzpEQKlSkuyH2ihM9V8B4ENHjx5MHDzRcMLCDAgMVGPy96MDkzRUfLqx0/vyghAYrBT58SHMATYobTXzQucLExYwbnkE/SDEawCMAI9BgAN6tz5czN2zQrs2jBQBqhepsiJHgTJIIVKLQ0A5aRwkeuI98+rOjxY' +
                    'YgMNJEabD+gfsSKcBXgHOQ7FBHFjAIAYITGqSQwgADiGYEAARGskMBBkCwAQhiiFEEF3hQoQAA8oEiyAc7AFCAAga0OCCFO8xnYiEoHkHhETHKOEggADsK' +
                    '" />';

var energyIcon = '<img src="' +
                    '' +
                    'e3HsyXH+nGHr6SH/fbHj05IOmfHoV0H/ezHlpEIFpPIK+hH/fMHve0Hsy0H9q0HmhUIKGSH6GWH/fKHvfUHvevHtqqHve5HvfPHvepHvfIHve+Hve2HoV9Hz0xIGhYIEs9IP///yH5BAEAAD8ALAAAAAANAA0AAA' +
                    'ZgwJ+wMCDcHg8ST8i0JGaT4okpdCl0K1OiQBXSGA6NggMA+ATCXsNwOIBrng/61+oEIOtDLkRhLhYoMTh3F11CJTY2KhKGPwgYMiAjjT8vIiwIlBUZKRGUPzA7n0Iboz9BADsK' +
                    '" />';

var killedMobsterIcon = '<img src="' +
                    '' +
                    'RgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCAAoACkDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEA' +
                    'wUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp' +
                    '6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhc' +
                    'RMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0' +
                    'tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwDy3UJ501CVUmkVRjADEDoKtGzvRawSR3UssspH7lFYtgqGzn0AZc9PvDrzirfrnUJfXj+QrXgvotRN1CYB9mWKWVo/PchGEeE4BA4IQcg9K' +
                    'VCnF0oaLZfkelmWKrrG1kpu3PLq+7GI8EIaGaeISC35kaSRx5pPTKEj5Qc9DyMVD9kuWhkki1BJSkZl2L5oLKCMkblAOM5PPQGn6LbiXXtNjPR7uJT/AN9itbRZ/tiGW/u1Kw3aSMZ5wCYpEdZgNxycqqDAyelbe' +
                    'ygvsr7ji+t4j/n5L72c7DNOZ4w0zkFhkFvetms5reGK+228zTQq42SsmwsM9SvOD7Vo15GaRUZRsrH3nCFWpUo1eeTeq3d+hj3kJkvZAAxLEKAvUkgDjHetOx02K1S5srfyxPIqpeTKNywruDCMYyXclRkDJ4IHR' +
                    'jW7o2reF9HP2i+057zUR02Qlth56l2CdMfdH61oTeJLeC2trm00qRtKmkw6i62CFud0flooAO0kj5sEYI6HbpRxddxUKdFuyWrsk/Q+QzKnD67Wbl9uX/pTMyx8P6g95p93oum3KXMMu5oL90iZihDLJtbHysOCB' +
                    'nBU8nINXJ/h1ew6lJCZ/Lt2JaEQQPOyx5ON5+VQcYzgmkl12806/sbhrqyXTblXVZbC1KTJHkoWHmZcEEkgAlSVIyRms+f7TdXN1oPiDUJJpPM3W93POzokmOCST/qpBjntlW6bgduXH1Hq4xX3v/I4b0V0bLM+g' +
                    'aBp9vIbjUma9WPMcUl3Hy+BgGOPLA5J6nHHpWNStot1YW4neGEQ7whkhnjlUMQSASjHBIU9fQ0lcGPpTpyjzz5mz7zg+SlRq2VtV+RSlgke4dgmVOMHI9K2tEW2FlqNvfXTW6TCIEBSxkRWLsFwCA/ChS2B8zZI7' +
                    'lFOGZVYwUElp6/5nVX4TwderOtKcrybb1XV3/lKV9PLqF287xLGCAqRKcrGgGFQewAA/U8mrv8AaaNb2yzaRZ3E9vCIRPO8hLKCduVV1HAIXkHhRRRV/wBq1v5V+P8AmY/6nYH+ef3x/wDkSObVLy4t2tiLeG2Zl' +
                    'YxW9vHErEZwTtUFsZPUnrVaiiuTEYqWIacklbsezleU0ctjKFFt82utv0SP/9kK' +
                    '" />';

var goodIcon = '<img src="' +
                    '' +
                    'F1AZG2UrTigxIJxEbSNm3aLE06yUwm42TEuDyIBwYu95zz3bPMT+EvC4x9tROG6eQ4blNOztnVSxkBPs2/FAThdk11TeD3eOrnYSw4Rmto+lJCw5+6/vEReREcQTgVU32WBQZsrnLgSMNOUScw3pwkuWqX10oFQP' +
                    'BbkGZZ9mHf+OtdF4buoKTIAC1hf+FlIC0ImFGAPes6sL3E0adU05qHqCHjkxPux5NvnBdH7sKmN0FLA1XFZnjXn1XzDz7vQSqbREZ5MxSPwOU4hK2GZs9ye/U5KjQesicY3rfpSTdZYTBjMQF0tIzKhVZ4NnhVwN' +
                    '6n3WAQVyAUolnAF5tG/7ZropbX1FKRmYj7qq/X+X5yFKU6gmJCKRXQsBbbcHKNWwV0DByDnsTBSxKSIjDBi2i2NKG7Yp+Hmkskhk4O719r4BagiLVBx+jAagj0rB4HGo+rgPODHpg4AWIui4Q4j5QQQlxIw9PUO0' +
                    'zF52KTZwZbLE2mJdjTcAt6zox/2dfEBHo/dGFqPgb3mkdhFeB622JpNJrQVn8Ti7jS/wIkhChcTX1hKplMDnlH29cayBQ04KChGOVjUVq8Grvrfszg8tBpGJlPyMn5NiRIcgaxrBkn6pUWorGo+2nontMfuaGsXS' +
                    'q8ZNTZcdTRr56PDuxAGfe54JNkGtWmI9hobPNQ09NTdpHlfTdH2wmNCVDUvwGy8lMJshWHV90X5ZSyxvzlbHTW7Z8fcT7zO5WAuAoxaCvQvurBjy286YKF9avJOUqP7cvcKNc0emxl5edUQDgcpjkt9zDIv9s1EL' +
                    'iCZCagzEEulJxPlJUGi1g7tiw9jTLNyr50Ot1aWVklFcSUh7AsuZQj6VOfZgbIl9lXSGRCqm8hZ0ONcSPqFm8WczzjFQXBVV5R+UtMv1t+JoSQToYhipwlVc6UTAUEUVDlbLWW/SHn7/7NSUl252Y9AAAAAElFTk' +
                    'SuQmCCCg==' +
                    '" />';

var mafiaHatIcon = '<img src="' +
                    '' +
                    'cHB7Ozsra2tlFRUJiLjGpqamBgYFVWVj0mJ4+QkFtTU1NUVGBiYk1HSJqjom5vb5ZbX6+vr2dnZzYHC7hLVDEwMXh1daipqWxeX28XHkdHR5h/gbYgLL+/v6Gnp5KYmJycnAAAACH5BAEAAD8ALAAAAAAYABIAAA' +
                    'b/wJ9w+PMYj0gjcSk0BjSPR+2x4ZQiDSWz2CgwHhyaRuADgD6jiGf7a4QYvgKB0OIIEi+AQNHYehoDH3IlKhoJDwIGJCVXWUR/DRkgBmIbCYkXITglIzAKWFwNBAkMDC8PlwYtJJoKIQQHKhcBHhERAiAAOyAvCS' +
                    'cGFiQErQopBzgHIQ0RPr2SLzUZA6oXJAcKAQErJZowEQUAGWR5Dz6/BTAEOAEzMw4owy0zAuInIlIJG9MFFyXrMyYmhChxwEAAAQJO9HCxgAeLHtNaqCihAOAEE/5IaMDBgcMAARV0yFiQowMNGxQgTJgQw0SIYh' +
                    'kIBLCgysAAFwh0IECA4cbKVYs4UgQgUcPCnxEcWhCAYaCDCwkYMECAQAEeDgUaABBY0+bCAA2ZShBQoUIYQQUFAZyYscTDDAsINaCDcQFGAQ0ZXmhQwHVLgwCcWhQYPKJEgD5MggAAOwo=' +
                    '" />';

var plussignIcon = '<img src="' +
                    '' +
                    'SmDYTwahxbEDxRNIyDcKFyCI7HBGPBNBiKiigjuHAaAoGi8NDEerMSWcaJ1Wwsjmt5xfrCOg43W3xmsyMAOwo=' +
                    '" />';

var bankIcon = '<img src="' +
                    '' +
                    'dCJZzKbDxkIluPc+Lxz6nUb2JbD+zMA5XCXJG9cj+MW3rAmnCxhVB/Zk+bckBTSN7bAsrDBMa/E9XDD1NcLkt2J6u5PMrlqGOOaIS7V6TObKjIf22NC4K6TmOHKJ6rQfLPAP///yH5BAEAAD8ALAAAAAAQABAAAA' +
                    'aMwJ9wSCwaj8hkUXBgMARKUKAm+mB4HZnxEJiIODkJBLKggTxDAgKzM/U6EFdE8rmdZp7VikCoDHQvc14FIwcEIYgrMAsPFQ44BQUcDgo2CRQUFzAPCwkoCA4mAQgNCT8CHhoxPg8bFhYsCAoNBlBDJAMlCgC8AA' +
                    'YZaEYCLRQAKSkZG0qnCQAqtsvRSUEAOwo=' +
                    '" />';

var healthIcon = '<img src="' +
                    '' +
                    'wAFgAAACH5BAEAAB8ALAAAAAAQABAAAAVm4CeOZGkaaGqShsdlgrGOBiQcjTx/Bu4MOlbKMKlYAEOdoZM5/ACajWJBVUIOkwEAM41QEAiloFHZKh4ISYJAUDotmjMiwbgEAsrhYs5IniISDHg7PBQJFwVBKwYIBA' +
                    'GJhEmKhCshADsK' +
                    '" />';

var foundIcon = '<img src="' +
                    '' +
                    'IgI1MpDcNMxT40m86Vus9739vRZmi/fOHhwOE9z3k/DoF1rvPpGQnaqYmGX6y09Grfu4GVPFlPcUnFFTlxOY+oZqefka9jIeLCfKq30zFVNTB0b43gQsOtTRh0iByRICylNNDlsPtJZTIXIcwX+6x5gFgt+d6fh0' +
                    'zXXrzsJ57CIs9pzMg0MrOUF0URqCBE2G2LAQqltxkIkbmdziRWwvZcrz7X8u8KKEjEkOUpnET4pe6iSP0FQYhlGNZMCBF4t2uSd7uH5V6KucbK0z2rBTkYNiNBSAfixu4W7K5zOuzpcoWyEwUah90Ww8nkHxiGGW' +
                    'm8WNa9WpCKIRbZhXQiFAWz2NGIm92cTDaLOQPD0mGFUvmaERl5RXFh72pBtkegRVqxWEmpsID3Peqr9u2NMujzxpmpuHnRxvlJVN+2KnQteMGazB1prhVBHobtSAjyBAVSkVJOLufCohK3pDUOPzBSQkHCMsALFF' +
                    'SsAs5E5pgUhDuwImAwFHskUyigLMsI2+Mi9zXONO3eiJ/qKwWQ4q54bSLsCd4LJaZ6qIsuPPf/HOzHEIpIOU6i1e9Rlff87lCoZRtBpA5Qe/nDSWMNNH9sg7c/2iHRP/v9sqD8St0m/C4dy3kxWLks0wT4SIMTbM' +
                    '+tLpM013AXusbvgzEwGRZ5DpoHK0Hvw4NacnBmWXCs6HiFxfwz7nH7o9zVJ+oaefipf7o2IlpzGA6EVy59DdR1F+B49uF7qMAYUPV3EnfG7wgODAvPDNKFtd65UW8tq67lQjfr1DvjI2teLVw94XCPwLbAfBCYaB' +
                    'j8XokDCeDFxUBGyOWyNW9QWnEpS0bEm59GRy/qDbHdyUlxC4ZoTZvpa22K2TYIPGVBQgTQeBshOehsJ+G5Q2sEaSlJvvbFxTdW69ypoZGxp0u57+ZxjmGh1OKaKJh3moNVnObLBom2iXfT2/qgSP4PU3k9tCVxAe' +
                    '4AAAAASUVORK5CYIIK' +
                    '" />';

var warningIcon = '<img src="' +
                    '' +
                    'Vmapq1qbEuaWq7Cu6s6+7OjLuz7zU7I1aYZXP5vWHm++Hzvu8R/OURJ15YGZWZJXePsNo/ZLUPYc9jS0ykQ0yWKKen2+1bG8T/AoS+tLf4J4UmeVFEaqaueX3Z8ZY1AxZGbm+e9y2OJttDFqoAeB+N2NMNRWm7mq' +
                    'bXBOAHb7YHJkMHHPnzYDEJYwNMsdA/yKi7deifgOCnqzu9I+E3jnyeuH0S5KiEApsE9wBYdpGlKrO+rWdVwMLHZl2El/pEPliWlRfAjYdALCbiTG0QnveA2Wbqs9qNFVkHn7A/Avjes0fH+4N3nBVz0FEB1zoAWQ' +
                    'GcqwtCDkvoeUZQXLnh8JZjb++tAPi7T9v8EwG3ycRvSncEwaR5NN8NKR2EcGmvABbX4duoEYJg86bnpBXmnugP/waYfXnkytd+//mSqilQYQosGsHlTgPMBuBkjWIcJ6CyDl3PzXCWp7XmN7ouLANmnzbkTrrmhr' +
                    'McnnW2pO8AUwKUoMtDYOKAsgxOMSCqBT/DYdxtlnJKHMV5p96Nq4CJttrO6aGx+m2VXk0nUREjGJll6rooRa8aJABMJhjoNsJRkPrIefHzfuLt2F3teuV5XVrpJWYrU7NY6rixnVPn9X3QwgokARLDBIO9RuYsz6' +
                    '4mrtaSD8Kct7Rwx6KyHy3JmFZNnFDVRBfVa2GasNBg7mEOJmvyIBlqyuOn3ZGUFVeK/TqJOjU7srRFICPTwBPf/ZokvSV5I8D9PJPlMFH7VN/p0poSDRKniIYCMz8A9QcpP1oZxJMAAAAASUVORK5CYIIK' +
                    '" />';

var cashIcon =    '<img src="' +
                    '' +
                    'dCJZzKbDxkIluPc+Lxz6nUb2JbD+zMA5XCXJG9cj+MW3rAmnCxhVB/Zk+bckBTSN7bAsrDBMa/E9XDD1NcLkt2J6u5PMrlqGOOaIS7V6TObKjIf22NC4K6TmOHKJ6rQfLPAP///yH5BAEAAD8ALAAAAAAQABAAAA' +
                    'aMwJ9wSCwaj8hkUXBgMARKUKAm+mB4HZnxEJiIODkJBLKggTxDAgKzM/U6EFdE8rmdZp7VikCoDHQvc14FIwcEIYgrMAsPFQ44BQUcDgo2CRQUFzAPCwkoCA4mAQgNCT8CHhoxPg8bFhYsCAoNBlBDJAMlCgC8AA' +
                    'YZaEYCLRQAKSkZG0qnCQAqtsvRSUEAOw==" />';

var hideIcon =    '<img src="' +
                    '' +
                    'waHPTy9FxaXPz+BKSWBDQyPPzKBGQCBJyavIRuDExOZCQmNCQWFGROBPzyBMQCBDw+ZBweHAwKDLSKBEwyBFQCBHxmBNze3FRSVDQCBGQ+DPzmBHx+fFxajLy+vJxyBBQSFLQCBBwaJPz+/PzWBJyazCwqRDw+dA' +
                    'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' +
                    'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACwAAAAAEAAQAAAHi4AAgoMAL4SHiDclM4iNGi0FjYcwLT+SkyUCMJeDJhUNE4Obgh6EFiguRRg6hoQeNUEQPgg7qz' +
                    'wKhzpBuhUGGx48t4QwNrsfCyI5AwoKpYQ+IDogEiE5MT6XEgEPIUIRGT0Ho4QEFxQsJD0OOByNEisJJwkyHtiIIxYmLhISHkQdHeyJYkCwYMFBgQAAOw==" />';


var cashElt, cash;              // Cash DOM element and value
var healthElt, health;          // Health DOM element and value
var energyElt, energy;          // Energy DOM element and value
var maxEnergyElt, maxEnergy;    // Maximum energy DOM element and value
var staminaElt, stamina;        // Stamina DOM element and value
var maxStaminaElt, maxStamina;  // Maximum stamina DOM element and value
var levelElt, level;            // Level DOM element and value
var curExpElt, curExp;          // Experience DOM element and value
var lvlExpElt, lvlExp;          // Level up experience DOM element and value
var ptsToNextLevel;             // Experience to next level up
var mafia;                      // Mafia size
var invites;                    // Number of mafia invitations
var staminaFloor;               // Stamina to reserve for manual play
var stats;                      // Skill points
var energyPack;                 // Is an energy pack waiting?
var autoStamBurnif;             // Can auto-burn be used now?

if (!initialized) {
  if (GM_getValue('leftAlign', 0)) {
    var mainFrame = xpath('//div[@class=\'UIStandardFrame_Container clearfix\']');
    if (mainFrame.snapshotLength>0) mainFrame.snapshotItem(0).setAttribute("style", "margin:0", 0);
  }
  if (GM_getValue('hideAds', 'checked')) {
    var adsTop = xpath('//div[@id=\''+SCRIPT.appID+'__zbar_34b435e07d\']');
    if (adsTop.snapshotLength>0) { adsTop.snapshotItem(0).setAttribute("style", "margin:0; height:0; display:none", 0); }
    var adsRight = xpath('//div[@class=\'UIStandardFrame_SidebarAds\']');
    if (adsRight.snapshotLength>0) { adsRight.snapshotItem(0).setAttribute("style", "margin:0; height:0; display:none", 0); }
  }

  var settingsOpen = false;
  var delay = Math.floor(parseFloat(GM_getValue('d1', '3')) + parseFloat((GM_getValue('d2', '5'))-parseFloat(GM_getValue('d1', '3')))*Math.random())*1000;;
  var defaultClans = ['{', '[', '(', '<'];

  var debug = (GM_getValue('enableDebug', '') == 'checked');

  var useClickSimulation = true;

  var propertyId = new Array(
    ['Mega Casino', 12],
    ['5-Star Hotel', 11],
    ['Office Building', 10],
    ['Marina Tourist Shops', 9],
    ['Valu-Mart', 8],
    ['Appartment Complex', 7],
    ['Italian Restaurant', 6]
    );

  // Define all jobs. The array elements are:
  // job description, unadjusted energy cost, job number, tab number
  var missions = new Array(
    ['Mugging',1,1,1],
    ['Corner Store Hold-up',3,2,1],
    ['Warehouse Robbery',5,3,1],
    ['Auto Theft',7,4,1],
    ['Beat Up Rival Gangster',2,5,1],
    ['Rob a Pimp',3,8,1],
    ['Collect on a Loan',2,37,1],
    ['Collect Protection Money',2,6,2],
    ['Rough Up Dealers',2,7,2],
    ['Take Out a Rogue Cop',3,9,2],
    ['Perform a Hit',3,10,2],
    ['Bank Heist',10,11,2],
    ['Jewelry Store Job',15,12,2],
    ['Hijack a Semi',8,38,2],
    ['Destroy Enemy Mob Hideout',5,13,3],
    ['Kill a Protected Snitch',5,14,3],
    ['Bust a Made Man Out of Prison',5,15,3],
    ['Museum Break-in',18,16,3],
    ['Fight a Haitian Gang',6,17,3],
    ['Clip the Irish Mob\'s Local Enforcer',10,39,3],
    ['Steal a Tanker Truck',8,40,3],
    ['Federal Reserve Raid',25,18,4],
    ['Smuggle Across the Border',7,19,4],
    ['Liquor Smuggling',30,22,4],
    ['Run Illegal Poker Game',20,26,4],
    ['Wiretap the Cops',30,28,4],
    ['Rob an Electronics Store',24,41,4],
    ['Burn Down a Tenement',18,42,4],
    ['Distill Some Liquor',10,23,4],
    ['Manufacture Tokens',10,24,4],
    ['Get Cheating Deck',10,25,4],
    ['Overtake Phone Central',10,27,4],
    ['Repel the Yakuza',13,29,5],
    ['Disrupt Rival Smuggling Ring',15,30,5],
    ['Invade Tong-controlled Neighborhood',25,31,5],
    ['Sell Guns to the Russian Mob',25,32,5],
    ['Protect your City against a Rival Family',35,33,5],
    ['Assassinate a Political Figure',35,34,5],
    ['Exterminate a Rival Family',40,35,5],
    ['Obtain Compromising Photos',28,43,5],
    ['Frame a Rival Capo',26,44,5],
    ['Steal an Air Freight Delivery',32,45,6],
    ['Run a Biker Gang Out of Town',35,46,6],
    ['Flip a Snitch',25,47,6],
    ['Steal Bank Records',30,48,6],
    ['Loot the Police Impound Lot',60,49,6],
    ['Recruit a Rival Crew Member',30,50,6],
    ['Dodge an FBI Tail',20,51,6],
    ['Whack a Rival Crew Leader',28,52,6],
    ['Influence a Harbor Official',50,53,7],
    ['Move Stolen Merchandise',36,54,7],
    ['Snuff a Rat',44,55,7],
    ['Help a Fugitive Flee the Country',40,56,7],
    ['Dispose of a Body',25,57,7],
    ['Ransom a Businessman\'s Kids',60,58,7],
    ['Fix the Big Game',50,59,7],
    ['Steal an Arms Shipment',45,60,7],
    ['Extort a Corrupt Judge',24,61,8],
    ['Embezzle Funds Through a Phony Company',50,62,8],
    ['Break Into the Armory',50,63,8],
    ['Rip Off the Armenian Mob',50,64,8],
    ['Muscle in on a Triad Operation',45,65,8],
    ['Ambush a Rival at a Sit Down',55,66,8],
    ['Order a Hit on a Public Official',35,67,8],
    ['Take Over an Identity Theft Ring',36,68,8],
    ['"Settle" a Beef... Permanently',40,69,9],
    ['Buy Off a Federal Agent',35,70,9],
    ['Make a Deal with the Mexican Cartel',40,71,9],
    ['Blackmail the District Attorney',44,72,9],
    ['Shake Down a City Council Member',85,73,9],
    ['Make Arrangements for a Visiting Don',40,74,9],
    ['Take Control of a Casino',70,75,9],
    ['Travel to the Old Country',52,76,9]
  );

  var itemCost = new Array(
    ['Baseball Bat',300],
    ['Crowbar',700],
    ['Colt Pistol',1000],
    ['Sawed-off Shotgun',2000],
    ['Grenade',3000],
    ['Machine Pistol',5500],
    ['Hacksaw',10000],
    ['Tommy Gun',120000],
    ['Chain Gun',200000],
    ['Bullet Proof Vest',6000],
    ['Body Armor',16000],
    ['Motorcycle',15000],
    ['Delivery Truck',20000],
    ['Sedan',40000],
    ['Armored Sedan',60000],
    ['Getaway Cruiser',90000],
    ['Town Car',400000],
    ['Speed Boat',400000]
  );

  var requirementJob = new Array(
    ['Liquor', 'Distill Some Liquor'],
    ['Tokens', 'Manufacture Tokens'],
    ['Wiretap Device', 'Overtake Phone Central'],
    ['1 Wiretap Device', 'Overtake Phone Central'],
    ['Cards', 'Get Cheating Deck'],
    ['Untraceable Cell Phone', 'Rob an Electronics Store'],
    ['Concealable Camera', 'Rob an Electronics Store'],
    ['Computer Set-Up', 'Rob an Electronics Store'],
    ['Blackmail Photos', 'Obtain Compromising Photos'],
    ['Illegal Transaction Records', 'Steal Bank Records'],
    ['.22 Pistol', 'Beat Up Rival Gangster'],
    ['Revolver', 'Beat Up Rival Gangster'],
    ['.9mm Semi-Automatic', 'Rob a Pimp'],
    ['Butterfly Knife', 'Collect Protection Money'],
    ['Rough Up Dealers', 'Brass Knuckles'],
    ['Tactical Shotgun', 'Perform a Hit'],
    ['.45 Revolver', 'Take Out a Rogue Cop'],
    ['C4', 'Destroy Enemy Mob Hideout'],
    ['Stab- Proof Vest', 'Kill a Protected Snitch'],
    ['Automatic Rifle', 'Bust a Made Man Out of Prison'],
    ['Lucky Shamrock Medallion', 'Clip the Irish Mob\'s Local Enforcer'],
    ['Semi-Automatic Shotgun', 'Fight a Haitian Gang'],
    ['Firebomb', 'Steal a Tanker Truck'],
    ['Armored Truck', 'Smuggle Across the Border'],
    ['Grenade Launcher', 'Repel the Yakuza'],
    ['.50 Caliber Rifle', 'Disrupt Rival Smuggling Ring'],
    ['Armored Car', 'Invade Tong-Controlled Neighborhood'],
    ['RPG Launcher', 'Sell Guns to the Russian Mob'],
    ['Bodyguards', 'Protect your City against a Rival Family'],
    ['Night Vision Goggles', 'Assassinate a Political Figure'],
    ['Napalm', 'Exterminate a Rival Family'],
    ['Prop Plane', 'Steal an Air Freight Delivery'],
    ['Harley Davidson', 'Run a Biker Gang Out of Town'],
    ['Luxury Yacht', 'Influence a Harbor Official'],
    ['Porsche 911', 'Ransom a Businessman\'s Kids'],
    ['Bookie\'s Holdout Pistol', 'Fix the Big Game'],
    ['AR-15 Assault Rifle', 'Rip Off the Armenian Mob'],
    ['Falsified Documents', 'Take Over an Identity Theft Ring'],
    ['Federal Agent', 'Buy Off a Federal Agent'],
    ['Private Jet', 'Make a Deal with the Mexican Cartel'],
    ['Police Cruiser', 'Blackmail the District Attorney'],
    ['Armoured Limousine', 'Shake Down a City Council Member']
  );

  String.prototype.trim = function() {
    return this.replace(/^\s+|\s+$/g,'');
  }
  String.prototype.ltrim = function() {
    return this.replace(/^\s+/,'');
  }
  String.prototype.rtrim = function() {
    return this.replace(/\s+$/,'');
  }

  Array.prototype.searchArray = function(searchStr,index) {
    // searches a multidimensional array
    // searchStr can be a regex
    var returnArray = false;
    for (i=0; i<this.length; i++) {
      if (typeof(searchStr) == 'function') {
        if (searchStr.test(this[i][index])) {
          if (!returnArray) { returnArray = [] }
          returnArray.push(i);
        }
      } else {
        if (this[i][index]===searchStr) {
          if (!returnArray) { returnArray = [] }
          returnArray.push(i);
        }
      }
    }
    return returnArray;
  }

  // Array.unique() - Remove duplicate values
  Array.prototype.unique = function() {
    var a = [];
    var l = this.length;
    for(var i=0; i<l; i++) {
      for(var j=i+1; j<l; j++) {
        // If this[i] is found later in the array
        if (this[i] === this[j])
          j = ++i;
      }
      a.push(this[i]);
    }
    return a;
  };

  //Check if isRunning is not set and then initialise it if so
  if (GM_getValue('isRunning') === '') {
    GM_setValue('isRunning', true);
  }


  //store isRunning so we can access it from the event call
  var isRunningStore = makeElement('div', document.body, {'style':'display:none;', 'id':'isRunningStore'}).appendChild(document.createTextNode(GM_getValue('isRunning', false)));;

  document.addEventListener('DOMNodeInserted', function(e){setTimeout(function(){ nodeInserted(e); }, 0);}, false);

  var Reload = new Animate();
  Reload.desc = 'reload';
  var Autoplay = new Animate();
  Autoplay.desc = 'auto-play';
  Autoplay.fx = loadHome;

  var initialized = true;
  DEBUG('Completed initialize.');
}

function Animate() {
  this.TOUT = null;
  this.desc = '';
  this.fx = null;
  this.delay = null;
}

Animate.prototype.clearTimeout = function() {
  if (this.TOUT) {
    DEBUG('Clearing ' + this.desc + ' timer ' + this.TOUT + '.');
    clearTimeout(this.TOUT);
    this.TOUT = null;
  }
}

Animate.prototype.setTimeout = function(fx, delay) {
  this.clearTimeout();
  this.fx = fx;
  this.delay = delay;
  // Make the handler clear TOUT. This prevents attempts
  // to clear timers that have already gone off.
  var obj = this;
  this.TOUT = window.setTimeout(function () { fx(); obj.TOUT = null; }, delay);
  DEBUG('Started ' + this.desc + ' timer ' + this.TOUT +
        ', delay=' + delay/1000 + ' sec.');
}

Animate.prototype.start = function() {
  if (GM_getValue('isRunning', false) === true && settingsOpen === false) {
    this.setTimeout(this.fx, this.delay);
  } else if(settingsOpen === true) {
    DEBUG('Settings box open. Not starting ' + this.desc + ' timer.');
  } else {
    DEBUG('Autoplayer paused. Not starting ' + this.desc + ' timer.');
  }
}

// Set up auto-reload (if enabled).
autoReload();

if (!refreshGlobalStats()) {
  // Unrecognized page. Reload.
  if (!document.body) {
    DEBUG('No body. Possible white out or slow load?');
  } else if (document.body.innerHTML.indexOf('Error while loading') != -1) {
    DEBUG('Error loading page.');
  } else {
    DEBUG('Can\'t read page. Possible white out?');
  }
  // Start the reload timer.
  Autoplay.delay = 10000;
  Autoplay.start();
  // Stop the script. (The timer will still go off and reload.)
  return;
}

// Accept any waiting invitations.
if (invites > 0) {
  addToLog('process Icon','Accepting ' + invites + (invites > 1 ? ' invites.' : ' invite.'));
  window.location = 'http://apps.facebook.com/' + SCRIPT.name +
                    SCRIPT.controller + 'recruit' +
                    SCRIPT.action + 'accept' +
                    SCRIPT.user + 'all';
  return;
}

refreshSettings();

if (GM_getValue('selectStaminaKeepOld', 0) != GM_getValue('selectStaminaKeep', 0) && (GM_getValue('autoFight', '') == 'checked' || GM_getValue('autoRob', '') == 'checked')) {
  GM_setValue('selectStaminaKeepOld', GM_getValue('selectStaminaKeep', 0));
  addToLog('info Icon', staminaIcon + '<font style="color:#04B4AE;";> Stamina is set to keep above <strong>' + staminaFloor + '</strong> for auto-fight/rob.</font>');
}

if (GM_getValue('allowStaminaToLevelUp')== 'checked' && GM_getValue('currentStamBurn') != GM_getValue('autoStamBurn')) {
   GM_setValue('currentStamBurn', GM_getValue('autoStamBurn'));
   addToLog('process Icon', '<font style="color:#009966;">Auto-burn stamina for level up is currently: <strong>' + GM_getValue('autoStamBurn') + '</strong>.</font>');
}

if (GM_getValue('logOpen', '') == 'open') {
  showMafiaLogBox();
}
return;
///////////////////////////////////////////////////////////////////////////////
//  End of top-level code. Automatic play is kicked off by nodeInserted().   //
///////////////////////////////////////////////////////////////////////////////


function doAutoPlay () {
  // Set the default auto-play timer function.
  Autoplay.fx = goHome;

  // Get the rest of the player's information.
  var autoMissionif = (GM_getValue('autoMission', '') == 'checked' && ((energy >= calcEnergyCost() && GM_getValue('waitForFull', '') != 'checked')  || (energy >= maxEnergy && GM_getValue('waitForFull', '') == 'checked')) && GM_getValue('isRunning', false) === true);
  var autoFightRobif = ((GM_getValue('autoFight', '') == 'checked' || GM_getValue('autoRob', '') == 'checked') && (stamina > staminaFloor || (GM_getValue('allowStaminaToLevelUp', '') == 'checked' && stamina >= (ptsToNextLevel / (GM_getValue('totalExpInt', 0) / ((GM_getValue('fightWinCountInt', 0) + GM_getValue('fightLossCountInt', 0)) + (GM_getValue('robWinCountInt', 0) + GM_getValue('robLossCountInt', 0))))).toFixed(0)))&& health>28 && GM_getValue('isRunning', false) === true);
  var pUpdates = xpath("//div[@class='update_item']");
  var pUpdatesLen = pUpdates.snapshotLength;

  //autoPause reset
  if (GM_getValue('autoPauseActivated', false) === true && GM_getValue('autoPauseBefore', '') == 'checked' && GM_getValue('autoPauselvlExp') < lvlExp) {
    GM_setValue('autoPauselvlExp', lvlExp);
    GM_setValue('autoPauseActivated', false);
  }


  // auto-repair
  if (GM_getValue('autoRepair', '') == 'checked' && GM_getValue('isRunning', false) === true && GM_getValue('propertyDamage', 0) == 2 ) {
    if (GM_getValue('propertyDamageCost', 0) > cash) {
      withdrawFromBank(GM_getValue('propertyDamageCost', 0) - cash);
    } else {
      var link = 'http://apps.facebook.com/' + SCRIPT.name + SCRIPT.controller + 'property' + SCRIPT.action + 'repair_all';
      takeAction(link, 'repair');
      Autoplay.delay = delay;
      Autoplay.start();
    }

  // auto-protect
  } else if (GM_getValue('autoProtect', '') == 'checked' && GM_getValue('isRunning', false) === true && GM_getValue('propertyDamage', 0) == 1 ) {
    if (GM_getValue('propertyDamageCost', 0) > cash) {
      withdrawFromBank(GM_getValue('propertyDamageCost', 0) - cash);
    } else {
      var link = 'http://apps.facebook.com/' + SCRIPT.name + SCRIPT.controller + 'property' + SCRIPT.action + 'protect_all';
      takeAction(link, 'protect');
      Autoplay.delay = delay;
      Autoplay.start();
    }

  // autoheal
  } else if (GM_getValue('autoHeal', '') == 'checked' &&
             health < GM_getValue('healthLevel', '') &&
             (health > 19 || GM_getValue('hideInHospital', '') != 'checked') &&
             GM_getValue('isRunning', false) === true) {
    var link = 'http://apps.facebook.com/' + SCRIPT.name + SCRIPT.controller + 'hospital' + SCRIPT.action + 'heal';
    takeAction(link,'heal');
    Autoplay.delay = delay;
    Autoplay.start();

  // bank logic here
  } else if (GM_getValue('autoBank', '') == 'checked' && cash>parseInt(GM_getValue('bankConfig', 100000))-1 && GM_getValue('isRunning', false) === true) {
    if (document.body.innerHTML.indexOf('title">The Bank') != -1) {
      bankClickDeposit();
    } else {
      Autoplay.fx = goBank;
      Autoplay.delay = delay;
      Autoplay.start();
      DEBUG('Entering the bank.');
    }

  // autostat
  } else if (GM_getValue('autoStat', '') == 'checked' && stats>0 && GM_getValue('isRunning', false) === true &&
    (GM_getValue('autoStatAttack', '') == 'checked' ||
    GM_getValue('autoStatDefense', '') == 'checked' ||
    GM_getValue('autoStatHealth', '') == 'checked' ||
    GM_getValue('autoStatEnergy', '') == 'checked' ||
    (GM_getValue('autoStatStamina', '') == 'checked' && stats >= 2))) {

    DEBUG('Stats available.');

    switch (GM_getValue('autoStatAdd','')) {
      case 'attack':
        var link = 'http://apps.facebook.com/' + SCRIPT.name + SCRIPT.controller + 'stats' + SCRIPT.action + 'upgrade' + '&upgrade_key=attack';
        break;
      case 'defense':
        var link = 'http://apps.facebook.com/' + SCRIPT.name + SCRIPT.controller + 'stats' + SCRIPT.action + 'upgrade' + '&upgrade_key=defense';
        break;
      case 'health':
        var link = 'http://apps.facebook.com/' + SCRIPT.name + SCRIPT.controller + 'stats' + SCRIPT.action + 'upgrade' + '&upgrade_key=max_health';
        break;
      case 'energy':
        var link = 'http://apps.facebook.com/' + SCRIPT.name + SCRIPT.controller + 'stats' + SCRIPT.action + 'upgrade' + '&upgrade_key=max_energy';
        break;
      case 'stamina':
        var link = 'http://apps.facebook.com/' + SCRIPT.name + SCRIPT.controller + 'stats' + SCRIPT.action + 'upgrade' + '&upgrade_key=max_stamina';
      default:
        addToLog('warning Icon', 'BUG DETECTED: Select a stat to increment or disable auto-stat.');
    }
    takeAction(link, 'stats');
    Autoplay.delay = delay;
    Autoplay.start();

  //autoPause logic
  } else if (GM_getValue('autoPause', '') == 'checked' && ((GM_getValue('autoPauseBefore', '') == 'checked' && GM_getValue('autoPauseExp', '') >= lvlExp - curExp && GM_getValue('autoPauseActivated', false) === false) || (GM_getValue('autoPauseAfter', '') == 'checked' && GM_getValue('autoPauselvlExp', '') < lvlExp)) && GM_getValue('isRunning', false) === true) {
    if (GM_getValue('autoPauseBefore', '') == 'checked') {
      addToLog('pause Icon', 'Auto-pause in effect. Experience threshold reached.');
      GM_setValue('autoPauseActivated', true);
      pause();
    } else {
      addToLog('pause Icon', 'Auto-pause in effect. Leveled up.');
      GM_setValue('autoPauselvlExp', lvlExp);
      pause();
    }

  // auto-buy properties
  } else if (GM_getValue('autoBuy', '') == 'checked' && GM_getValue('isRunning', false) === true &&
             GM_getValue('buyCost', 0) < (cash - GM_getValue('buyMinAmount', 0)) &&
             (!(autoMissionif && energy >= maxEnergy)) &&
             (!(autoFightRobif && stamina >= maxStamina)) ) {
    if (document.getElementById(SCRIPT.appID+'_property')) {
      propertyBuy();
    } else {
      Autoplay.fx = goPropertyTab;
      Autoplay.delay = delay;
      Autoplay.start();
    }

  // Decide whether stamina or energy is higher in % and then act on the fullest
  // one so as to try to not waste any refill time. If they are both not ready
  // to run then just move on and check each one like normal.
  } else if (autoMissionif && autoFightRobif) {
    if((energy/maxEnergy) >= (stamina/maxStamina)) {
      autoMission();
    } else {
      autoFightRob();
    }

  //autoMission logic
  } else if (autoMissionif) {
    autoMission();

  // autofight or autorob
  } else if (autoFightRobif) {
    autoFightRob();

  // auto-energypack
  } else if (GM_getValue('autoEnergyPack', '') == 'checked' && GM_getValue('isRunning', false) === true && energy <= 2 && energyPack === true) {
    var ptsFromEnergyPack = parseFloat(GM_getValue('estimateJobRatio', '1.0'))*maxEnergy*1.25;
    var ptsToLevelProjStaminaUse = (ptsToNextLevel-stamina*(GM_getValue('totalExpInt', 0) / ((GM_getValue('fightWinCountInt', 0) + GM_getValue('fightLossCountInt', 0)) + (GM_getValue('robWinCountInt', 0) + GM_getValue('robLossCountInt', 0)))).toFixed(2));
    if (ptsFromEnergyPack <= ptsToLevelProjStaminaUse) {  
      var link = 'http://apps.facebook.com/' + SCRIPT.name + SCRIPT.controller + 'index' + SCRIPT.action + 'use_and_energy_all';
      takeAction(link, 'energypack');
      Autoplay.delay = delay;
      Autoplay.start();
    }
    else{
      DEBUG('Auto-Energypack Not Executed, ptsFromEnergyPack=' + ptsFromEnergyPack + ' is NOT less than or equal to ptsToLevelProjStaminaUse=' + ptsToLevelProjStaminaUse);
    }

  // auto-playerUpdates
  } else if (GM_getValue('logPlayerUpdates', '') == 'checked' && pUpdatesLen) {
    // Process each update.
    DEBUG('Parsing Player Updates.');
    while (pUpdatesLen) {
      parsePlayerUpdates(pUpdates.snapshotItem(--pUpdatesLen));
    }

    // Delete all player updates.
    var link = 'http://apps.facebook.com/' + SCRIPT.name +
               SCRIPT.controller + 'index' +
               SCRIPT.action + 'deletenews';
    takeAction(link, 'deletenews');

  //check for property damage, this way we are not adding any overhead, except on pages that we are not doing anything anyways.
  } else if ((GM_getValue('autoProtect', '') == 'checked' || GM_getValue('autoRepair', '') == 'checked') && GM_getValue('propertyDamage', 0) == 0 && GM_getValue('isRunning', false) === true) {
    var link = 'http://apps.facebook.com/' + SCRIPT.name + SCRIPT.controller + 'property' + SCRIPT.action + 'view';
    takeAction(link, 'propDmgChk');
  }

  // Set up auto-reload (if enabled).
  autoReload();
}

function autoReload() {
  if (GM_getValue('autoClick', '') == 'checked') {
    Reload.fx    = loadHome;
    Reload.delay = Math.floor(parseFloat(GM_getValue('r1', '30')) +
                   parseFloat((GM_getValue('r2', '110')) -
                   parseFloat(GM_getValue('r1', '30')))*Math.random())*1000;
    Reload.start();
  }
}

function autoMission() {
  var jobno       = missions[GM_getValue('selectMission', 1)][2];
  var tabno       = missions[GM_getValue('selectMission', 1)][3];

  if (onJobTab(tabno))
  {
    // No need to switch job tabs. Just do the job.
    var link = 'http://apps.facebook.com/' + SCRIPT.name +
               SCRIPT.controller + 'job' +
               SCRIPT.action + 'dojob&job=' + jobno + '&tab=' + tabno;
    takeAction(link, 'job');
    return;
  }

  DEBUG('Switching to job tab ' + tabno + '.');
  window.location = 'http://apps.facebook.com/' + SCRIPT.name +
                    SCRIPT.controller + 'job' +
                    SCRIPT.action + 'view' +
                    '&tab=' + tabno +
                    '&bar=' + (tabno < 6? '0' : '1');
}

function onJobTab(tabno) {
  // See if we already visited the tab.
  var tabStoreElt = document.getElementById('jobTabStore');
  var tabStore    = tabStoreElt? tabStoreElt.firstChild.nodeValue : '';
  if (tabStore == tabno) {
    DEBUG('Already visited job tab ' + tabno + '.');
    return true;
  }

  // See if we're on the indicated job tab.
  var barElt = document.getElementById(SCRIPT.appID + '_jobs_bar' +
                                       (tabno < 6? '0' : '1'));
  if (barElt) {
    var elt = xpath('//li[contains(@class, \'tab_on\')]//a', barElt).snapshotItem(0);
    if (elt) {
      elt.href.match(/tab=(\d+)/);
      if (RegExp.$1 == tabno) {
        // We're on the correct tab. Store this information in the page.
        if (tabStoreElt) {
          tabStoreElt.firstChild.nodeValue = tabno;
          DEBUG('Updated jobTabStore element. Now on tab ' + tabno + '.');
        } else {
          makeElement('div', document.body, {'style':'display:none;', 'id':'jobTabStore'}).appendChild(document.createTextNode(tabno));
          DEBUG('Created jobTabStore element. Now on tab ' + tabno + '.');
        }
        return true;
      } else {
        DEBUG('On job tab ' + RegExp.$1 + '.');
      }
    } else {
      DEBUG('No tab_on link element found.');
    }
  } else {
    DEBUG('Job bar element not found.');
  }
  return false;
}

function autoFightRob() {
  var id = 0;

  if (autoStamBurnif) {
    GM_setValue('autoStamBurn', 'Running');
  } else {
    GM_setValue('autoStamBurn', 'Stopped');
  }

  // Get an opponent.
  if (GM_getValue('fightRandom', '') == 'checked') {
    id = findFightOpponent();
  }
  if (GM_getValue('rFightList', '') == 'checked') {
    id = parseInt(GM_getValue('fightList', ''));
  }

  if (id) {
    GM_setValue('fightOpponent', String(id));
    if (GM_getValue('autoRob', '') == 'checked') {
      // Rob the filthy animal
      DEBUG('Rob the filthy animal ' + id + '.');
      var link = 'http://apps.facebook.com/'+ SCRIPT.name +
        SCRIPT.controller + 'racket' +
        SCRIPT.action + 'attack' +
        SCRIPT.opponent + id +
        '&property_id=' +
        parseInt(GM_getValue('propertyId', '')); // will only rob casinos...
      takeAction(link, 'rob');
      setFightOpponentRobbed();
      Autoplay.delay = delay;
      Autoplay.start();
    } else {
      // Attack!
      var link = 'http://apps.facebook.com/' + SCRIPT.name +
        SCRIPT.controller + 'fight' +
        SCRIPT.action + 'attack' +
        SCRIPT.opponent + id;
      takeAction(link, 'fight');
      Autoplay.delay = delay;
      Autoplay.start();
    }
  }
}

function bankClickDeposit() {
  var sform = xpath('//input[@value=\'Deposit\' and @type=\'submit\']');
  if(sform.snapshotItem(0) == null ) {
    window.setTimeout(bankClickDeposit,1000);
  } else {
    sform.snapshotItem(0).click();
    bankDepositCheck();
  }
}

function bankDepositCheck() {
  var elt = xpath('//td[@class=\'message_body\' and contains(text(),\'was deposited\')]').snapshotItem(0);
  if (elt) {
    addToLog('process Icon', bankIcon + elt.innerHTML);
    Autoplay.delay = delay;
    Autoplay.start();
  } else {
    window.setTimeout(bankDepositCheck,1000);
  }
}

function placeBounty () {
  var depositBox = xpath('//input[@name="amount"]');
  depositBox.snapshotItem(0).value = GM_getValue('bountyAmount',10000);
  var sform = xpath('//input[@type="submit"]');
  sform.snapshotItem(0).click();
  placeBountyCheck();
}

function placeBountyCheck () {
  if ( xpath('//td[@class=\'message_body\' and contains(text(),\'You just set a\')]').snapshotItem(0) != null ) {
    DEBUG('Bounty set successfully.');
  } else {
    DEBUG('Bounty not set.');
  }
}

// Searches the fight table in the given element for new
// random targets. Returns a new opponent, or undefined.
function findNewFightOpponent(element) {
  // Use fight semantics?
  var fight = (GM_getValue('autoFight', '') == 'checked');
  if (!fight && GM_getValue('autoRob', '') != 'checked') {
    addToLog('warning Icon', 'BUG DETECTED: reached findNewFightOpponent() without fight or rob.');
    return;
  }

  // Don't bother searching if we still have plenty.
  var newOpponents = getSavedList('fightListNew');
  var len = newOpponents.length;
  if (len >= 50) {
    return newOpponents[Math.floor(Math.random() * len)];
  }

  // Check the fight table.
  var opponents  = xpath('//table[@class=\'main_table fight_table\']//a[contains(@href,\'opponent_id\') and not(contains(@href,\'property\'))]', element);
  var opponentsLen = opponents.snapshotLength;
  if (!opponentsLen) {
    // No opponents displayed on this page.
    return newOpponents[Math.floor(Math.random() * len)];
  }

  var opponentMafiaMax = parseInt(GM_getValue('fightmafiaSize', '502'));
  var opponentMafiaMin = parseInt(GM_getValue('fightmafiaMinSize', '1'));
  var opponentLevelMax = parseInt(GM_getValue('fightLevel', '100'));
  // Make any relative adjustments (if enabled).
  if (GM_getValue('fightLevelRelative', false)) {
    opponentLevelMax = opponentLevelMax + level;
  }
  if (GM_getValue('fightMafiaRelative', false)) {
    opponentMafiaMax = opponentMafiaMax + mafia;
  }

  if (GM_getValue('fightMafiaMinRelative', false)) {
    opponentMafiaMin = mafia - opponentMafiaMin;
  }
  // Make a blacklist of opponents.
  var avoidList = getSavedList('fightListAvoid');
  DEBUG('new=' + newOpponents);
  DEBUG('avoid=' + avoidList);
  var blacklist = newOpponents.concat(avoidList);
  if (!fight) {
    var robList = getSavedList('fightListRobbed');
    blacklist = blacklist.concat(robList);
    DEBUG('robbed=' + robList);
  } else if (GM_getValue('fightStealth', '') == 'checked' || newOpponents.length) {
    var activeList   = getSavedList('fightListActive');
    var inactiveList = getSavedList('fightListInactive');
    blacklist = blacklist.concat(activeList, inactiveList);
    DEBUG('inactive=' + inactiveList);
    DEBUG('active=' + activeList);
  }
  DEBUG('Looking for new opponents.');

  // Thanks Liquidor for the loop code
  // Examine each potential opponent in the displayed list.
  for (var i = 0; i < opponentsLen; i++) {
    var row           = opponents.snapshotItem(i).parentNode.parentNode;
    var rowData       = row.getElementsByTagName('td');
    // We need this for robbing to go to the previous tr that contains the
    // name and level. (In the fight list it is all on one line.)
    if(!fight) {
      var nameAndLevel = row.previousSibling;
      while ( nameAndLevel.nodeType != 1 ) {
        nameAndLevel = nameAndLevel.previousSibling;
      }
    } else {
      nameAndLevel = row;
    }
    var opponentMafia = rowData[1] ? parseInt(rowData[1].innerHTML) : 0;
    var opponentLevel = parseInt(nameAndLevel.innerHTML.split('Level ')[1]);
    var userElt       = nameAndLevel.getElementsByTagName('a')[0];
    var username      = userElt? userElt.innerHTML : '';
    if (!opponentLevel) {
      addToLog('warning Icon','BUG DETECTED: Unable to read opponent level.');
    } else if (!opponentMafia) {
      addToLog('warning Icon','BUG DETECTED: Unable to read opponent mafia.');
    } else if (!username) {
      addToLog('warning Icon','BUG DETECTED: Unable to read opponent name.');
      addToLog('warning Icon', 'Row contents: '+ row.innerHTML);
    } else if (opponentLevel <= opponentLevelMax &&
               opponentMafia <= opponentMafiaMax &&
               opponentMafia >= opponentMafiaMin &&
               notFamily(username)) {
      // This opponent is acceptable. Save the ID (if new).
      var link = opponents.snapshotItem(i).toString();
      var id = parseInt(link.split(SCRIPT.opponent)[1]);

      if (id) {
        var idString = id.toString();

        if (blacklist.indexOf(idString) == -1) {
          newOpponents.push(idString);
          DEBUG('<span style="color:#BCD2EA;">'+'Found new opponent ' + username + ' (' + idString + ').'+ '</span>');
        }
      }
    }
  }
  if (newOpponents.length > len) {
    setSavedList('fightListNew', newOpponents);
  }

  return newOpponents[Math.floor(Math.random() * newOpponents.length)];
}

// Finds a fight opponent.
//
// Returns an opponent if one is found. Otherwise, nothing
// is returned and the fight page will soon be loaded.
function findFightOpponent() {
  // To be stealthy, we try to only attack inactive opponents.
  // If we have enough acceptable opponents, attack them randomly.
  // If not, try any new opponents first and move them into the
  // the appropriate list: active, inactive, or avoid.

  // Check for any new opponents.
  var opponent = findNewFightOpponent(document.body);
  var opponentList;
  var len;

  // For stealth mode fights, if we don't have a new opponent then
  // choose one of the inactive opponents we've already fought.
  if (!opponent &&
      GM_getValue('autoFight', '') == 'checked' &&
      GM_getValue('fightStealth', '') == 'checked') {
    opponentList = getSavedList('fightListInactive');
    len = opponentList.length;
    opponent = opponentList[Math.floor(Math.random() * len)];
  }

  if (!opponent) {
    // Go to the fight or rob page to find opponents.
    if (GM_getValue('autoRob', '') == 'checked') {
      addToLog('process Icon', '<span style="color:#BCD2EA;">'+ 'No opponents. Going to rob list.' + '</span>');
      Autoplay.fx = function(){document.location = 'http://apps.facebook.com/inthemafia/remote/html_server.php?&xw_controller=racket&xw_action=view'}
      Autoplay.delay = delay;
      Autoplay.start();
    } else {
      addToLog('process Icon', '<span style="color:#BCD2EA;">'+ 'No opponents. Going to fight list.' + '</span>');
      Autoplay.fx = goFightTab;
      Autoplay.delay = delay;
      Autoplay.start();
    }
    return;
  }

  return opponent;
}

function setFightOpponentActive() {
  var opponent = GM_getValue('fightOpponent', '');
  if (!opponent) {
    return;
  }

  // Add the opponent to the active list.
  DEBUG('Marking opponent ' + opponent + ' active.');
  addSavedListItem('fightListActive', opponent, 10);

  // Remove the opponent from the other fight lists.
  removeSavedListItem('fightListInactive', opponent);
  removeSavedListItem('fightListNew', opponent);
  removeSavedListItem('fightListAvoid', opponent);
}

function setFightOpponentInactive() {
  var opponent = GM_getValue('fightOpponent', '');
  if (!opponent) {
    return;
  }

  // Add the opponent to the inactive list.
  DEBUG('Marking opponent ' + opponent + ' inactive.');
  addSavedListItem('fightListInactive', opponent, 10);

  // Remove the opponent from the other fight lists.
  removeSavedListItem('fightListActive', opponent);
  removeSavedListItem('fightListNew', opponent);
  removeSavedListItem('fightListAvoid', opponent);
}

function setFightOpponentRobbed() {
  var opponent = GM_getValue('fightOpponent', '');
  if (!opponent) {
    return;
  }

  // Add the opponent to the robbed list.
  DEBUG('Marking opponent ' + opponent + ' robbed.');
  addSavedListItem('fightListRobbed', opponent, 10);

  // Remove the opponent from the other fight lists.
  removeSavedListItem('fightListNew', opponent);
}

function setFightOpponentAvoid() {
  var opponent = GM_getValue('fightOpponent', '');
  if (!opponent) {
    return;
  }

  // Add the opponent to the avoid list.
  DEBUG('Marking opponent ' + opponent + ' avoid.');
  addSavedListItem('fightListAvoid', opponent, 50);

  // Remove the opponent from all other fight lists.
  removeSavedListItem('fightListActive', opponent);
  removeSavedListItem('fightListInactive', opponent);
  removeSavedListItem('fightListNew', opponent);
  removeSavedListItem('fightList', opponent);
}

function toggleSettings() {
  if (settingsOpen === false) {
    settingsOpen = true;
    if(!document.getElementById('settingsBoxBg') && !document.getElementById('settingsBox')) {
      //setup menu
      createMenu();
    } else {
      showSettingsBox();
    }
    // Stop any running timer so the settings box won't disappear.
    Autoplay.clearTimeout();
  } else {
    settingsOpen = false;
    if(document.getElementById('settingsBoxBg') && document.getElementById('settingsBox')) {
      hideSettingsBox();
    }
    Autoplay.delay = 150;
    Autoplay.start();
  }
}

function showSettingsBox() {
  var settingsBgDiv = document.getElementById('settingsBoxBg');
  var settingsBoxContainer = document.getElementById('GenDialogPopDialog');
  settingsBgDiv.style.display = 'block';
  settingsBoxContainer.style.display = 'block';
}

function showMafiaLogBox() {
  if(!document.getElementById('mafiaLogBox')) {
    createLogBox();
  } else {
    var mafiaLogBoxDiv = document.getElementById('mafiaLogBox');
    mafiaLogBoxDiv.style.display = 'block';
  }
  if(GM_getValue('autoLog', '') != 'checked' && GM_getValue('logOpen', 'closed') != 'open') {
    alert('Logging is not enabled, to see anything here please go into\nthe Settings, the General tab, and check Enable logging.');
  }
  GM_setValue('logOpen', 'open');
}

function hideSettingsBox() {
  if(document.getElementById('settingsBoxBg')) {
    var settingsBgDiv = document.getElementById('settingsBoxBg');
    var settingsBoxContainer = document.getElementById('GenDialogPopDialog');
    settingsBoxContainer.style.display = 'none';
    settingsBgDiv.style.display = 'none';
  }
}

function hideMafiaLogBox() {
  var mafiaLogBoxDiv = document.getElementById('mafiaLogBox');
  mafiaLogBoxDiv.style.display = 'none';
  GM_setValue('logOpen', 'closed');
}

function saveSettings() {
  // Validate the settings and alert the user if the settings are invalid.
  var autoBankOn      = (document.getElementById('autoBank').checked === true);
  var bankConfig      = document.getElementById('bankConfig').value;
  var bankConfigInt   = parseInt(bankConfig);
  if (autoBankOn && (isNaN(bankConfigInt) || bankConfigInt < 1)) {
    alert('Minimum auto-bank amount must be 1 or higher');
    return;
  }
  var autoFightOn     = (document.getElementById('autoFight').checked === true);
  var autoRobOn       = (document.getElementById('autoRob').checked === true);
  var autoFightRandom = (document.getElementById('fightRandom').checked === true);
  var fightLevelRelative = (document.getElementById('fightLevelRelative').checked === true);
  var fightMafiaRelative = (document.getElementById('fightMafiaRelative').checked === true);
  var fightMafiaMinRelative = (document.getElementById('fightMafiaMinRelative').checked === true);
  var fightLevel = parseInt(document.getElementById('fightLevel').value);
  var fightMafia = parseInt(document.getElementById('fightmafiaSize').value);
  var fightMafiaMin = parseInt(document.getElementById('fightmafiaMinSize').value);
  var estimateJobRatio = parseInt(document.getElementById('estimateJobRatio').value);
  var energyPack      =  (document.getElementById('autoEnergyPack').checked === true );

  if ((autoFightOn || autoRobOn) && autoFightRandom) {
    // Validate the fight level settings.
    if (isNaN(fightLevel)) {
      alert('Please enter a maximum fight level.');
      return;
    } else if (fightLevelRelative && (fightLevel < 0)) {
      alert('Please enter a relative fight level of zero or more.');
      return;
    } else if (!fightLevelRelative && (fightLevel < level)) {
      alert('Please enter a fight level of ' + level +
            ' (your current level) or more.');
      return;
    }

    // Validate the fight mafia size settings.
    if (isNaN(fightMafia)) {
      alert('Please enter a maximum mafia size for fighting.');
      return;
    } else if (!fightMafiaRelative && (fightMafia < 1)) {
      alert('Please enter a maximum mafia size of one or more for fighting.');
      return;
    } else if (fightMafiaRelative && (fightMafia + mafia < 1)) {
      alert('Please enter a larger relative mafia size for fighting.');
      return;
    }

    // Validate the fight mafia minimum size settings.
    if (isNaN(fightMafiaMin)) {
      alert('Please enter a minimum mafia size for fighting.');
      return;
    } else if (!fightMafiaMinRelative && (fightMafiaMin < 1)) {
      alert('Please enter a minimum mafia size of one or more for fighting.');
      return;
    } else if (fightMafiaMinRelative && (mafia - fightMafiaMin < 1)) {
      alert('Please enter a smaller relative mafia size for fighting.');
      return;
    }
  }
  // Validate the estimated job ratio setting.
  if (energyPack) {
    if (isNaN(estimateJobRatio)) {
      alert('Please enter a number between 0 and 3 for your estimated job xp to energy ratio');
      return;
    }
  }

  // All settings are valid. Save them.
  if (document.getElementById('autoClick').checked === true) {
    GM_setValue('autoClick', 'checked');
  } else {
    GM_setValue('autoClick', 0);
  }

  if (document.getElementById('autoLog').checked === true) {
    GM_setValue('autoLog', 'checked');
  } else {
    GM_setValue('autoLog', 0);
  }

  if (document.getElementById('logPlayerUpdates').checked === true) {
    GM_setValue('logPlayerUpdates', 'checked');
  } else {
    GM_setValue('logPlayerUpdates', 0);
  }

  if (document.getElementById('hideAttacks').checked === true) {
    GM_setValue('hideAttacks', 'checked');
  } else {
    GM_setValue('hideAttacks', 0);
  }

  if (document.getElementById('autoHitlist').checked === true) {
    GM_setValue('autoHitlist', 'checked');
  } else {
    GM_setValue('autoHitlist', 0);
  }


  if (document.getElementById('clanMember').checked === true) {
    GM_setValue('clanMember', 'checked');
  } else {
    GM_setValue('clanMember', 0);
  }

  if (document.getElementById('autoMission').checked === true) {
    GM_setValue('autoMission', 'checked');
  } else {
    GM_setValue('autoMission', 0);
  }

  if (document.getElementById('repeatJob').checked === true) {
    GM_setValue('repeatJob', 'checked');
  } else {
    GM_setValue('repeatJob', 0);
  }

  if (autoBankOn) {
    GM_setValue('autoBank', 'checked');
  } else {
    GM_setValue('autoBank', 0);
  }

  if (document.getElementById('autoHeal').checked === true) {
    GM_setValue('autoHeal', 'checked');
  } else {
    GM_setValue('autoHeal', 0);
  }

  if (document.getElementById('hideInHospital').checked === true) {
    GM_setValue('hideInHospital', 'checked');
  } else {
    GM_setValue('hideInHospital', 0);
  }

  if (document.getElementById('autoStat').checked === true) {
    GM_setValue('autoStat', 'checked');
  } else {
    GM_setValue('autoStat', 0);
  }

  if (document.getElementById('autoStatAttack').checked === true) {
    GM_setValue('autoStatAttack', 'checked');
    GM_setValue('autoStatAdd', 'attack');
  } else {
    GM_setValue('autoStatAttack', 0);
  }

  if (document.getElementById('autoStatDefense').checked === true) {
    GM_setValue('autoStatDefense', 'checked');
    GM_setValue('autoStatAdd', 'defense');
  } else {
    GM_setValue('autoStatDefense', 0);
  }

  if (document.getElementById('autoStatHealth').checked === true) {
    GM_setValue('autoStatHealth', 'checked');
    GM_setValue('autoStatAdd', 'health');
  } else {
    GM_setValue('autoStatHealth', 0);
  }

  if (document.getElementById('autoStatEnergy').checked === true) {
    GM_setValue('autoStatEnergy', 'checked');
    GM_setValue('autoStatAdd', 'energy');
   } else {
    GM_setValue('autoStatEnergy', 0);
  }

  if (document.getElementById('autoStatStamina').checked === true) {
    GM_setValue('autoStatStamina', 'checked');
    GM_setValue('autoStatAdd', 'stamina');
  } else {
    GM_setValue('autoStatStamina', 0);
  }

  var selectProperties = '';
  if (document.getElementById('abandoned').checked === true ) {
    GM_setValue('abandoned', 'checked');
    selectProperties += 'Abandoned Lot';
  } else {
    GM_setValue('abandoned', 0);
  }
  if (document.getElementById('commercial').checked === true ) {
    GM_setValue('commercial', 'checked');
    selectProperties += 'Commercial Block';
  } else {
    GM_setValue('commercial', 0);
  }
  if (document.getElementById('downtown').checked === true ) {
    GM_setValue('downtown', 'checked');
    selectProperties += 'Prime Downtown Lot';
  } else {
    GM_setValue('downtown', 0);
  }
  if (document.getElementById('beachfront').checked === true ) {
    GM_setValue('beachfront', 'checked');
    selectProperties += 'Beachfront Property';
  } else {
    GM_setValue('beachfront', 0);
  }
  if (document.getElementById('mike').checked === true ) {
    GM_setValue('mike', 'checked');
    selectProperties += 'Mafia Mike\'s';
  } else {
    GM_setValue('mike', 0);
  }
  if (document.getElementById('rent').checked === true ) {
    GM_setValue('rent', 'checked');
    selectProperties += 'Rent House';
  } else {
    GM_setValue('rent', 0);
  }
  if (document.getElementById('restaurant').checked === true ) {
    GM_setValue('restaurant', 'checked');
    selectProperties += 'Italian Restaurant';
  } else {
    GM_setValue('restaurant', 0);
  }
  if (document.getElementById('apartment').checked === true ) {
    GM_setValue('apartment', 'checked');
    selectProperties += 'Apartment Complex';
  } else {
    GM_setValue('apartment', 0);
  }
  if (document.getElementById('valu').checked === true ) {
    GM_setValue('valu', 'checked');
    selectProperties += 'Valu-Mart';
  } else {
    GM_setValue('valu', 0);
  }
  if (document.getElementById('tourist').checked === true ) {
    GM_setValue('tourist', 'checked');
    selectProperties += 'Marina Tourist Shops';
  } else {
    GM_setValue('tourist', 0);
  }
  if (document.getElementById('office').checked === true ) {
    GM_setValue('office', 'checked');
    selectProperties += 'Office Building';
  } else {
    GM_setValue('office', 0);
  }
  if (document.getElementById('hotel').checked === true ) {
    GM_setValue('hotel', 'checked');
    selectProperties += '5-Star Hotel';
  } else {
    GM_setValue('hotel', 0);
  }
  if (document.getElementById('casino').checked === true ) {
    GM_setValue('casino', 'checked');
    selectProperties += 'Mega Casino';
  } else {
    GM_setValue('casino', 0);
  }
  GM_setValue('selectProperties', selectProperties);

  if(document.getElementById('autoBuy').checked === true ) {
    GM_setValue('autoBuy', 'checked');
  } else { GM_setValue('autoBuy', 0); }

  if(document.getElementById('autoBuy').checked === true ) {
    GM_setValue('autoBuy', 'checked');
  } else { GM_setValue('autoBuy', 0); }

  if(document.getElementById('autoRepair').checked === true ) {
    GM_setValue('autoRepair', 'checked');
  } else { GM_setValue('autoRepair', 0); }

  if(document.getElementById('autoProtect').checked === true ) {
    GM_setValue('autoProtect', 'checked');
  } else { GM_setValue('autoProtect', 0); }

  if(document.getElementById('autoEnergyPack').checked === true ) {
    GM_setValue('autoEnergyPack', 'checked');
  } else { GM_setValue('autoEnergyPack', 0); }

  GM_setValue('estimateJobRatio', document.getElementById('estimateJobRatio').value);

  if(document.getElementById('hasHelicopter').checked === true ) {
    GM_setValue('hasHelicopter', 'checked');
  } else { GM_setValue('hasHelicopter', 0); }
  
  if (document.getElementById('autoPause').checked === true) {
    GM_setValue('autoPause', 'checked');
  } else {
    GM_setValue('autoPause', 0);
  }

  if (document.getElementById('autoPauseBefore').checked === true) {
    GM_setValue('autoPauseBefore', 'checked');
    GM_setValue('autoPauselvlExp', lvlExp);
    GM_setValue('autoPauseActivated', false);
  } else {
    GM_setValue('autoPauseBefore', 0);
  }

  if (document.getElementById('autoPauseAfter').checked === true) {
    GM_setValue('autoPauseAfter', 'checked');
    GM_setValue('autoPauselvlExp', lvlExp);
  } else {
    GM_setValue('autoPauseAfter', 0);
  }

  if (document.getElementById('hideAds').checked === true) {
    GM_setValue('hideAds', 'checked');
  } else {
    GM_setValue('hideAds', 0);
  }

  if (document.getElementById('leftAlign').checked === true) {
    GM_setValue('leftAlign', 'checked');
  } else {
    GM_setValue('leftAlign', 0);
  }

  if (document.getElementById('waitForFull').checked === true) {
    GM_setValue('waitForFull', 'checked');
  } else {
    GM_setValue('waitForFull', 0);
  }

  //two stamina burners won't work so autofight will take priority
  if (autoRobOn) {
    GM_setValue('autoRob', 'checked');
  } else {
    GM_setValue('autoRob', 0);
  }

  if (autoFightOn) {
    GM_setValue('autoFight', 'checked');
    GM_setValue('autoRob', 0);
  } else {
    GM_setValue('autoFight', 0);
  }

  if (document.getElementById('fightRandom').checked === true) {
    GM_setValue('fightRandom', 'checked');
  } else {
    GM_setValue('fightRandom', 0);
  }

  if (document.getElementById('fightStealth').checked === true) {
    GM_setValue('fightStealth', 'checked');
  } else {
    GM_setValue('fightStealth', 0);
  }

  if (document.getElementById('fightAvoidBodyguards').checked === true) {
    GM_setValue('fightAvoidBodyguards', 'checked');
  } else {
    GM_setValue('fightAvoidBodyguards', 0);
  }

  if (fightLevelRelative) {
    GM_setValue('fightLevelRelative', 'checked');
  } else {
    GM_setValue('fightLevelRelative', 0);
  }

  if (fightMafiaRelative) {
    GM_setValue('fightMafiaRelative', 'checked');
  } else {
    GM_setValue('fightMafiaRelative', 0);
  }

  if (fightMafiaMinRelative) {
    GM_setValue('fightMafiaMinRelative', 'checked');
  } else {
    GM_setValue('fightMafiaMinRelative', 0);
  }
  if (document.getElementById('rFightList').checked === true) {
    GM_setValue('rFightList', 'checked');
  } else {
    GM_setValue('rFightList', 0);
  }

  if (document.getElementById('allowStaminaToLevelUp').checked === true) {
    GM_setValue('allowStaminaToLevelUp', 'checked');
  } else {
    GM_setValue('allowStaminaToLevelUp', 0);
  }

  GM_setValue('clanName', document.getElementById('clanName').value);
  GM_setValue('selectMission', document.getElementById('selectMission').selectedIndex );
  GM_setValue('bankConfig', bankConfig);
  GM_setValue('r1', document.getElementById('r1').value);
  GM_setValue('r2', document.getElementById('r2').value);
  GM_setValue('d1', document.getElementById('d1').value);
  GM_setValue('d2', document.getElementById('d2').value);
  GM_setValue('fightList', document.getElementById('fightList').value);
  GM_setValue('propertyId', '12');
  GM_setValue('healthLevel', document.getElementById('healthLevel').value);
  GM_setValue('fightLevel', fightLevel);
  GM_setValue('fightmafiaSize', fightMafia);
  GM_setValue('fightmafiaMinSize', fightMafiaMin);
  GM_setValue('selectEnergyBonus', document.getElementById('selectEnergyBonus').selectedIndex );
  GM_setValue('selectStaminaKeep', document.getElementById('selectStaminaKeep').selectedIndex );
  GM_setValue('autoPauseExp', document.getElementById('autoPauseExp').value);
  GM_setValue('autoLogLength', document.getElementById('autoLogLength').value);
  GM_setValue('bountyAmount', document.getElementById('bountyAmount').value);
  GM_setValue('buyMinAmount', document.getElementById('buyMinAmount').value);

  // Clear any new random opponents.
  setSavedList('fightListNew', []);
  setSavedList('jobsToDo', []);
  setSavedList('itemList', []);

  toggleSettings();
  alert('settings saved');
}

function pause() {
  if(GM_getValue('isRunning', false) === true) {
    GM_setValue('isRunning', false);
    Autoplay.clearTimeout();
    Reload.clearTimeout();
    addToLog('pause Icon','Autoplayer is paused... (Log & stats do not track manual activity.)');

    var lobjTitleRow = document.getElementById(SCRIPT.appID + '_mw_masthead');
    lobjTitleRow.removeChild(document.getElementById('pauseButton'));
    var lobjplayButton = makeElement('span', lobjTitleRow, {'style':'top: 18px'});
    lobjplayButton.appendChild(document.createTextNode('resume'));
    lobjplayButton.addEventListener('click', unPause, false);
    makeElement('div', lobjTitleRow, {'style':'background: transparent url(' + stripURI(pausedMessageImage) + ') no-repeat scroll 20px; position: absolute; top: 0; left: 0; bottom: 0; width: 250px'});
    document.getElementById('isRunningStore').firstChild.nodeValue = 'false';
  }
}

function unPause() {
  if (GM_getValue('isRunning', false) === false) {
    GM_setValue('isRunning', true);
    addToLog('play Icon', 'Autoplayer resuming...');
  }
  //FIXME: Instead of completely reloading the page, why not hide the
  //       paused message image and change "resume" to "pause"? Then
  //       navigate via goHome() rather than loadHome().
  Autoplay.fx = loadHome;
  Autoplay.delay = 150;
  Autoplay.start();
}

function calcEnergyCost() {
  if (missions[GM_getValue('selectMission', 1)][1] > 5) {
    return Math.floor(missions[GM_getValue('selectMission', 1)][1] * (1 - GM_getValue('selectEnergyBonus',0)/100));
  } else {
    return missions[GM_getValue('selectMission', 1)][1];
  }
}

function notFamily(username) {
  if (GM_getValue('clanMember', '') == 'checked') {
    var clans = GM_getValue('clanName', '').split('\n');
    for (var i=0;i<clans.length;i++) {
      if (clans[i] && username.indexOf(clans[i]) != -1) {
        return false;
      }
    }
  }
  return true;
}

function addToLog(icon, line) {
  if (GM_getValue('autoLog', '') != 'checked') {
    // Logging is turned off.
    return;
  }

  var currentTime = new Date();
  var hours = currentTime.getHours();
  if (hours >= 12) {
    hours = hours - 12;
    var ampm = ' PM';
  } else {
    var ampm = ' AM';
  }
  if (hours == 0) {
    hours = 12;
  }
  var m_names = new Array('Jan', 'Feb', 'Mar',
    'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',
    'Oct', 'Nov', 'Dec');

  var timestampdate = m_names[currentTime.getMonth()] + ' ' + currentTime.getDate();
  var timestamptime = hours + ':' +
    (currentTime.getMinutes() < 10 ? 0 : '') +
    currentTime.getMinutes() + ':' +
    (currentTime.getSeconds() < 10 ? 0 : '') +
    currentTime.getSeconds() +
    ampm;
  var lineToAdd = '<div class="logEvent ' + icon + '"><div class="eventTime">' + timestampdate + '<br/>' + timestamptime + '</div><div class="eventBody">' + line + '</div><div class="clear"></div></div>';
  var itemLog = document.createElement('div');
  itemLog.innerHTML = lineToAdd + GM_getValue('itemLog', '');
  var itemLogForm = xpath('//div[contains(@class,\'logEvent\')]', itemLog);
  for (var i = itemLogForm.snapshotLength - 1; i >= GM_getValue('autoLogLength', 300); i--) {
    itemLog.removeChild(itemLogForm.snapshotItem(i));
  }
  //make sure log is cleaned when this new code is run, so we can actually detect the log length
  if ( itemLogForm.snapshotLength == 0 ) {
    itemLog.innerHTML = '';
  }

  GM_setValue('itemLog',itemLog.innerHTML);
  if (!debug) {
    var logBoxVar = document.getElementById('logBox');
    if (logBoxVar) {
      logBoxVar.innerHTML = itemLog.innerHTML;
    }
  }
}


function updateLogStats() {
  var fightCount = document.getElementById('fightCount');
  if (!fightCount) return;
    fightCount.firstChild.nodeValue = makeCommaValue(GM_getValue('fightWinCountInt', 0) + GM_getValue('fightLossCountInt', 0));

  document.getElementById('fightWinCount').firstChild.nodeValue = makeCommaValue(GM_getValue('fightWinCountInt', 0));

  var fightWinPct = (GM_getValue('fightWinCountInt', 0)/(GM_getValue('fightWinCountInt', 0) + GM_getValue('fightLossCountInt', 0)) * 100).toFixed(1);
    document.getElementById('fightWinPct').firstChild.nodeValue =  (isNaN(fightWinPct)) ? '0.0%' : fightWinPct + '%';

  document.getElementById('fightLossCount').firstChild.nodeValue = makeCommaValue(GM_getValue('fightLossCountInt', 0));

  var fightLossPct = (GM_getValue('fightLossCountInt', 0)/(GM_getValue('fightWinCountInt', 0) + GM_getValue('fightLossCountInt', 0)) * 100).toFixed(1)
    document.getElementById('fightLossPct').firstChild.nodeValue =  (isNaN(fightLossPct)) ? '0.0%' : fightLossPct + '%';

  document.getElementById('robCount').firstChild.nodeValue = makeCommaValue(GM_getValue('robWinCountInt', 0) + GM_getValue('robLossCountInt', 0));

  document.getElementById('robWinCount').firstChild.nodeValue = makeCommaValue(GM_getValue('robWinCountInt', 0));

  var robWinPct = (GM_getValue('robWinCountInt', 0)/(GM_getValue('robWinCountInt', 0) + GM_getValue('robLossCountInt', 0)) * 100).toFixed(1);
    document.getElementById('robWinPct').firstChild.nodeValue =  (isNaN(robWinPct)) ? '0.0%' : robWinPct + '%';

  document.getElementById('robLossCount').firstChild.nodeValue = makeCommaValue(GM_getValue('robLossCountInt', 0));

  var robLossPct = (GM_getValue('robLossCountInt', 0)/(GM_getValue('robWinCountInt', 0) + GM_getValue('robLossCountInt', 0)) * 100).toFixed(1);
    document.getElementById('robLossPct').firstChild.nodeValue =  (isNaN(robLossPct)) ? '0.0%' : robLossPct + '%';

  document.getElementById('totalWinDollars').firstChild.nodeValue = '$' + makeCommaValue(GM_getValue('totalWinDollarsInt', 0));  //Accomodates up to $999,999,999,999

  document.getElementById('totalLossDollars').firstChild.nodeValue = '$' + makeCommaValue(GM_getValue('totalLossDollarsInt', 0));

  document.getElementById('totalExp').firstChild.nodeValue = makeCommaValue(GM_getValue('totalExpInt', 0));

  var expRate = (GM_getValue('totalExpInt', 0) / ((GM_getValue('fightWinCountInt', 0) + GM_getValue('fightLossCountInt', 0)) + (GM_getValue('robWinCountInt', 0) + GM_getValue('robLossCountInt', 0)))).toFixed(2);
    document.getElementById('expRate').firstChild.nodeValue = (isNaN(expRate)) ? 0 : expRate;

  document.getElementById('expToNext').firstChild.nodeValue = makeCommaValue(ptsToNextLevel);

  var stamToNext = (ptsToNextLevel / (GM_getValue('totalExpInt', 0) / ((GM_getValue('fightWinCountInt', 0) + GM_getValue('fightLossCountInt', 0)) + (GM_getValue('robWinCountInt', 0) + GM_getValue('robLossCountInt', 0))))).toFixed(0);
    document.getElementById('stamToNext').firstChild.nodeValue = (isNaN(stamToNext)) ? 0 : stamToNext;
}

function debugOnOff() {
  if (GM_getValue('enableDebug') == 'checked') {
    GM_setValue('enableDebug', 0);
    debug = false;
    addToLog('info Icon', 'Debug logging disabled.');
    GM_setValue('debugSettingsDump', 'false');
    GM_setValue('autoLog', GM_getValue('priorLogSetting'));
  } else {
    GM_setValue('enableDebug', 'checked');
    debug = true;
    GM_setValue('priorLogSetting', GM_getValue('autoLog'));
    GM_setValue('autoLog', 'checked');
    addToLog('info Icon', 'Debug logging enabled.');
    if (GM_getValue('debugSettingsDump') != 'true') {
      debugDumpSettings();
      GM_setValue('debugSettingsDump', 'true');
    }
  }
  location.reload();
}

function DEBUG(line, level) {
  var level = (level == null) ? 0 : level;
  if (debug) {
    addToLog('info Icon', line);
    GM_log(line, level);
  }
}

function makeCommaValue(nStr) {
  nStr += '';
  x = nStr.split('.');
  x1 = x[0];
  var rgx = /(\d+)(\d{3})/;
  while (rgx.test(x1)) {
    x1 = x1.replace(rgx, '$1' + ',' + '$2');
  }
  return x1;
}

function showIfUnchecked(setting) {
  if (setting == '0') {
    setting = 'un-checked';
  }
  return setting;
}

function showIfSelected(setting) {
  if (setting == '0') {
    setting = 'not selected';
  } else {
    setting = 'selected';
  }
  return setting;
}

// Save an array of strings. The strings must not contain "\n".
function setSavedList(listName, list) {
  GM_setValue(listName, list.join('\n'));
}

// Get an array of strings that was saved with setSavedList().
function getSavedList(listName) {
  var savedList = GM_getValue(listName, '');
  return savedList? savedList.split('\n') : [];
}

// Add an item to a list saved with setSavedList().
// If the size of the list is greater than the "max"
// parameter, the first item in the list is removed.
function addSavedListItem(listName, item, max) {
  var savedList = getSavedList(listName);

  // Only add if it isn't already there.
  if (savedList.indexOf(item) != -1) {
    return;
  }

  savedList.push(item);
  if (max > 0) {
    while (max < savedList.length) {
      var item = savedList.shift();
      DEBUG('Removing ' + item + ' from ' + listName + '.');
    }
  }
  setSavedList(listName, savedList);
}

// Remove an item from a list saved with setSavedList().
function removeSavedListItem(listName, item) {
  var savedList = getSavedList(listName);
  var idx = savedList.indexOf(item);
  if (idx != -1) {
    savedList.splice(idx, 1);
    setSavedList(listName, savedList);
  }
}

function CycleFightList() {
  // Move the first opponent to the end of the list.
  var opponents = GM_getValue('fightList', '').split('\n');
  var first = opponents.shift();
  if (first) {
    opponents.push(first);
  }
  GM_setValue('fightList', opponents.join('\n'));
}

function CyclePropertyList() {
  DEBUG('CyclePropertyList(): '+ GM_getValue('propertyId', ''));
  if (GM_getValue('propertyId') <= 6) {
    CycleRobList();
    var i = 12; //back to casinos
  } else {
    var i = GM_getValue('propertyId') - 1;
  }
  GM_setValue('propertyId', i);
}

function clearLog() {
  GM_setValue('itemLog', '');

  //reset the log box
  var logBox = document.getElementById('logBox');
    logBox.innerHTML = '';
}

function clearStats() {
  //reset log statistics
  GM_setValue('fightWinCountInt', 0);

  GM_setValue('fightLossCountInt', 0);

  GM_setValue('robWinCountInt', 0);

  GM_setValue('robLossCountInt', 0);

  GM_setValue('totalExpInt', 0);

  GM_setValue('totalWinDollarsInt', 0);

  GM_setValue('totalLossDollarsInt', 0);

  GM_setValue('lastHitXp', 0);
  GM_setValue('totalHits', 0);
  GM_setValue('totalXp', 0);
  GM_setValue('currentHitXp',0);

  updateLogStats();
}

function clearHitlistArray () {
  GM_setValue('onHitlist', 0);
}

function clearHitStats () {
  GM_setValue('lastHitXp', 0);
  GM_setValue('totalHits', 0);
  GM_setValue('totalXp', 0);
  GM_setValue('currentHitXp',0);
}

function minBankCheck() {
  //don't allow zero value in autobank setting.
  var amount = parseInt(document.getElementById('bankConfig').value);
  if (isNaN(amount) || amount < 1) {
    alert('Minimum auto-bank amount must be 1 or higher');
    document.getElementById('bankConfig').focus();
  }
}

//update the script (by Richard Gibson; changed by ms99 and blannie)
function updateScript() {
  try {
    if (!GM_getValue) {
      return;
    }
    GM_xmlhttpRequest({
      method: 'GET',
      url: SCRIPT.url + '?source', // don't increase the 'installed' count; just for checking
      onload: function(result) {
        if (result.status != 200) {
          return;
        }
        if (!result.responseText.match(/@version\s+([\d.]+)/)) {
          return;
        }
        var theOtherVersion = RegExp.$1;
        if (theOtherVersion == SCRIPT.version) {
          alert('you have the latest version' + ' (v ' + SCRIPT.version + ') !');
          return;
        } else if (theOtherVersion < SCRIPT.version) {
          alert('Beta version' + ' (v ' + SCRIPT.version + ') installed ?!');
          return;
        } else {
          if (window.confirm('new version ' + ' (v ' + theOtherVersion + ') available!\n\n' + 'Do you want to update?' + '\n')) {
            clearSettings();
            window.location.href = SCRIPT.url;
          }
        }
      }
    });
  } catch (ex) {
    DEBUG(ex);
  }
}

function takeAction(link,action) {
  GM_setValue('actionType',action);
  DEBUG('Action set to: '+ action);
  GM_xmlhttpRequest({ method: 'GET',
    url: link,
    headers:{'Content-type':'application/x-www-form-urlencoded'},
    onload: function(responseDetails) { logResponse(responseDetails, action); },
    onerror: function(responseDetails) { addToLog('warning Icon', 'error status '+ responseDetails.status); }
  });
}

function withdrawFromBank(withdrawcash) {
  if (document.body.innerHTML.indexOf('title">The Bank') != -1) {
    GM_setValue('withdrawcash', withdrawcash);
    bankClickWithdraw();
  } else {
    Autoplay.fx = goBank;
    Autoplay.delay = delay;
    Autoplay.start();
    DEBUG('Entering the bank.');
  }
}

function bankClickWithdraw() {
  DEBUG('Withdrawing: '+GM_getValue('withdrawcash'));
  var sform = xpath('//input[@value=\'Withdraw\' and @type=\'submit\']');
  if(sform.snapshotItem(0) == null ) {
    DEBUG('sform null');
    window.setTimeout(bankClickWithdraw,1000);
  } else {
    DEBUG('Setting amount to take out.');
    xpath('//form[@id=\''+SCRIPT.appID+'_bank_withdraw\']/table/tbody/tr/td/input[@name=\'amount\']').snapshotItem(0).value = GM_getValue('withdrawcash');
    sform.snapshotItem(0).click();
    bankWithdrawCheck();
  }
}

function bankWithdrawCheck() {
  if ( xpath('//td[@class=\'message_body\' and contains(text(),\'You withdrew\')]').snapshotItem(0) == null ) {
    window.setTimeout(bankWithdrawCheck,1000);
  } else {
    addToLog('process Icon', '<span style="color:#885588;">Withdrew <span style="color:#52E259; font-weight:bold;">$'+makeCommaValue(GM_getValue('withdrawcash'))+'</span> from the bank.</span>');
    Autoplay.delay = delay;
    Autoplay.start();
  }
}

function createLogBox() {

  makeElement('style', document.getElementsByTagName('head')[0], {'type':'text/css'}).appendChild(document.createTextNode(
    '#mafiaLogBox div.mouseunderline:hover{text-decoration:underline}' +
    '#mafiaLogBox .logEvent{border-bottom:1px solid #333; padding:4px 0px}' +
    '#mafiaLogBox .eventTime{color:#888; font-size: 11px; width:75px;  float:left}' +
    '#mafiaLogBox .eventBody{width:315px; float:right}' +
    '#mafiaLogBox .eventTime,#mafiaLogBox .eventIcon,#mafiaLogBox .eventBody{}' +
    '#mafiaLogBox .clear{clear:both}' +
    '#mafiaLogBox .logEvent.Icon{background-repeat: no-repeat; background-position: 75px}' +
    '#mafiaLogBox .logEvent.process.Icon{background-image:url(' + stripURI(processIcon) + ')}' +
    '#mafiaLogBox .logEvent.search.Icon{background-image:url(' + stripURI(searchIcon) + ')}' +
    '#mafiaLogBox .logEvent.warning.Icon{background-image:url(' + stripURI(warningIcon) + ')}' +
    '#mafiaLogBox .logEvent.info.Icon{background-image:url(' + stripURI(infoIcon) + ')}' +
    '#mafiaLogBox .logEvent.lootbag.Icon{background-image:url(' + stripURI(lootbagIcon) + ')}' +
    '#mafiaLogBox .logEvent.found.Icon{background-image:url(' + stripURI(lootbagIcon) + ')}' +
    '#mafiaLogBox .logEvent.updateGood.Icon{background-image:url(' + stripURI(updateGoodIcon) + ')}' +
    '#mafiaLogBox .logEvent.updateBad.Icon{background-image:url(' + stripURI(updateBadIcon) + ')}' +
    '#mafiaLogBox .logEvent.pause.Icon{background-image:url(' + stripURI(pauseIcon) + ')}' +
    '#mafiaLogBox .logEvent.play.Icon{background-image:url(' + stripURI(playIcon) + ')}' +
    '#mafiaLogBox .logEvent.good.Icon{background-image:url(' + stripURI(goodIcon) + ')}' +
    '#mafiaLogBox .logEvent.bad.Icon{background-image:url(' + stripURI(badIcon) + ')}' +
    '#mafiaLogBox .logEvent.experience.Icon{background-image:url(' + stripURI(experienceIcon) + ')}' +
    '#mafiaLogBox .logEvent.experience.Icon{background-image:url(' + stripURI(experienceIcon) + ')}' +
    '#mafiaLogBox .logEvent.health.Icon{background-image:url(' + stripURI(healthIcon) + ')}' +
    '#mafiaLogBox .logEvent.cash.Icon{background-image:url(' + stripURI(cashIcon) + ')}'
  ));


  var mafiaLogBox = makeElement('div', document.body, {'id':'mafiaLogBox', 'style':'position: fixed; right: 5px; top: 30px; bottom: 30px; width: 427px; background: black url(http://mwdirectfb3.static.zynga.com/mwfb/graphics/MW_FB_Background_760.gif); text-align: left; padding: 5px; border: 1px solid; border-color: #FFFFFF; z-index: 98; font-size: 10pt;'});

  var logClrButton = makeElement('div', mafiaLogBox, {'class':'mouseunderline', 'style':'position: absolute; left: 5px; top: 0px; font-weight: 600; cursor: pointer; color: rgb(255, 217, 39);'});
    logClrButton.appendChild(document.createTextNode('clear log'));
    logClrButton.addEventListener('click', clearLog, false);

  var logClrStatsButton = makeElement('div', mafiaLogBox, {'class':'mouseunderline', 'style':'position: absolute; left: 85px; top: 0px; font-weight: 600; cursor: pointer; color: rgb(255, 217, 39);'});
    logClrStatsButton.appendChild(document.createTextNode('clear stats'));
    logClrStatsButton.addEventListener('click', clearStats, false);

  var closeLogButton = makeElement('div', mafiaLogBox, {'class':'mouseunderline', 'style':'position: absolute; right: 5px; top: 0px; font-weight: 600; cursor: pointer; color: rgb(255, 217, 39);'});
    closeLogButton.appendChild(document.createTextNode('close mafia log'));
    closeLogButton.addEventListener('click', hideMafiaLogBox, false);

  if ( debug ) {
    makeElement('div', mafiaLogBox, {'style':'position: absolute; left: 180px; top: 0px; font-weight: 600;color: rgb(255, 0, 0);'}).appendChild(document.createTextNode('Debug Log'));
  }

  var logBox = makeElement('div', mafiaLogBox, {'id':'logBox', 'style':'position: absolute; overflow: scroll; right: 0px; top: 20px; bottom: 68px; width: 425px; background-color: #111111; font-size:11px; color: #BCD2EA; text-align: left; padding: 5px; border: 1px solid;'});
    logBox.innerHTML = GM_getValue('itemLog', '');

  makeElement('div', mafiaLogBox, {'style':'position: absolute; left: 5px; bottom: 33px; font-weight: 100;color: #666666;'}).appendChild(document.createTextNode('Fights:'));

  makeElement('div', mafiaLogBox, {'id':'fightCount', 'style':'position: absolute; right: 335px; bottom: 33px; font-weight: 600;color: #BCD2EA;'}).appendChild(document.createTextNode(makeCommaValue(GM_getValue('fightWinCountInt', 0) + GM_getValue('fightLossCountInt', 0))));

  makeElement('div', mafiaLogBox, {'style':'position: absolute; left: 5px; bottom: 18px; font-weight: 100;color: #666666;'}).appendChild(document.createTextNode('Won:'));

  makeElement('div', mafiaLogBox, {'id':'fightWinCount', 'style':'position: absolute; right: 335px; bottom: 18px; font-weight: 600;color: #52E259;'}).appendChild(document.createTextNode(makeCommaValue(GM_getValue('fightWinCountInt', 0))));

  var fightWinPct = (GM_getValue('fightWinCountInt', 0)/(GM_getValue('fightWinCountInt', 0) + GM_getValue('fightLossCountInt', 0)) * 100).toFixed(1);
    makeElement('div', mafiaLogBox, {'id':'fightWinPct', 'style':'position: absolute; right: 280px; bottom: 18px; font-weight: 100;color: #52E259;'}).appendChild(document.createTextNode((isNaN(fightWinPct)) ? '0.0%' : fightWinPct + '%'));

  makeElement('div', mafiaLogBox, {'style':'position: absolute; left: 5px; bottom: 3px; font-weight: 100;color: #666666;'}).appendChild(document.createTextNode('Lost:'));

  makeElement('div', mafiaLogBox, {'id':'fightLossCount', 'style':'position: absolute; right: 335px; bottom: 3px; font-weight: 600;color: #EC2D2D;'}).appendChild(document.createTextNode(makeCommaValue(GM_getValue('fightLossCountInt', 0))));

  var fightLossPct = (GM_getValue('fightLossCountInt', 0)/(GM_getValue('fightWinCountInt', 0) + GM_getValue('fightLossCountInt', 0)) * 100).toFixed(1);
    makeElement('div', mafiaLogBox, {'id':'fightLossPct', 'style':'position: absolute; right: 280px; bottom: 3px; font-weight: 100;color: #EC2D2D;'}).appendChild(document.createTextNode((isNaN(fightLossPct)) ? '0.0%' : fightLossPct + '%'));

  makeElement('div', mafiaLogBox, {'style':'position: absolute; left: 165px; bottom: 33px; font-weight: 100;color: #666666;'}).appendChild(document.createTextNode('Robs:'));

  makeElement('div', mafiaLogBox, {'id':'robCount', 'style':'position: absolute; right: 185px; bottom: 33px; font-weight: 600;color: #BCD2EA;'}).appendChild(document.createTextNode(makeCommaValue((GM_getValue('robWinCountInt', 0) + GM_getValue('robLossCountInt', 0)))));

  makeElement('div', mafiaLogBox, {'style':'position: absolute; left: 165px; bottom: 18px; font-weight: 100;color: #666666;'}).appendChild(document.createTextNode('Succ:'));

  makeElement('div', mafiaLogBox, {'id':'robWinCount', 'style':'position: absolute; right: 185px; bottom: 18px; font-weight: 600;color: #52E259;'}).appendChild(document.createTextNode(makeCommaValue(GM_getValue('robWinCountInt', 0))));

  var robWinPct = (GM_getValue('robWinCountInt', 0)/(GM_getValue('robWinCountInt', 0) + GM_getValue('robLossCountInt', 0)) * 100).toFixed(1);
    makeElement('div', mafiaLogBox, {'id':'robWinPct', 'style':'position: absolute; right: 130px; bottom: 18px; font-weight: 100;color: #52E259;'}).appendChild(document.createTextNode((isNaN(robWinPct)) ? '0.0%' : robWinPct + '%'));

  makeElement('div', mafiaLogBox, {'style':'position: absolute; left: 165px; bottom: 3px; font-weight: 100;color: #666666;'}).appendChild(document.createTextNode('Fail:'));

  makeElement('div', mafiaLogBox, {'id':'robLossCount', 'style':'position: absolute; right: 185px; bottom: 3px; font-weight: 600;color: #EC2D2D;'}).appendChild(document.createTextNode(makeCommaValue(GM_getValue('robLossCountInt', 0))));

  var robLossPct = (GM_getValue('robLossCountInt', 0)/(GM_getValue('robWinCountInt', 0) + GM_getValue('robLossCountInt', 0)) * 100).toFixed(1);
    makeElement('div', mafiaLogBox, {'id':'robLossPct', 'style':'position: absolute; right: 130px; bottom: 3px; font-weight: 100;color: #EC2D2D;'}).appendChild(document.createTextNode((isNaN(robLossPct)) ? '0.0%' : robLossPct + '%'));

  makeElement('div', mafiaLogBox, {'id':'totalWinDollars', 'style':'position: absolute; right: 5px; bottom: 18px; font-weight: 600;color: #52E259;'}).appendChild(document.createTextNode('$' + makeCommaValue(GM_getValue('totalWinDollarsInt', 0))));  //Accomodates up to $999,999,999,999

  makeElement('div', mafiaLogBox, {'id':'totalLossDollars', 'style':'position: absolute; right: 5px; bottom: 3px; font-weight: 600;color: #EC2D2D;'}).appendChild(document.createTextNode('$' + makeCommaValue(GM_getValue('totalLossDollarsInt', 0))));

  makeElement('div', mafiaLogBox, {'style':'position: absolute; left: 5px; bottom: 50px; font-size: 11px; font-weight: 100;color: #666666;'}).appendChild(document.createTextNode('Exp Gained:'));

  makeElement('div', mafiaLogBox, {'id':'totalExp', 'style':'position: absolute; right: 329px; bottom: 50px; font-size: 11px; font-weight: 600;color: #52E259;'}).appendChild(document.createTextNode(makeCommaValue(GM_getValue('totalExpInt', 0))));

  makeElement('div', mafiaLogBox, {'style':'position: absolute; left: 7px; bottom: 47px; font-size: 11px; font-weight: 100;color: #666666;'}).appendChild(document.createTextNode('______________________________________________________________________'));

  makeElement('div', mafiaLogBox, {'style':'position: absolute; right: 5px; bottom: 33px; font-weight: 100;color: #666666;'}).appendChild(document.createTextNode('Total $ Won/Lost'));

  makeElement('div', mafiaLogBox, {'style':'position: absolute; right: 267px; bottom: 50px; font-size: 11px; font-weight: 100;color: #666666;'}).appendChild(document.createTextNode('Gain Rate:'));

  var expRate = (GM_getValue('totalExpInt', 0) / ((GM_getValue('fightWinCountInt', 0) + GM_getValue('fightLossCountInt', 0)) + (GM_getValue('robWinCountInt', 0) + GM_getValue('robLossCountInt', 0)))).toFixed(2);
    makeElement('div', mafiaLogBox, {'id':'expRate', 'style':'position: absolute; right: 240px; bottom: 50px; font-size: 11px; font-weight: 600;color: #04B4AE;'}).appendChild(document.createTextNode((isNaN(expRate)) ? 0 : expRate));

  makeElement('div', mafiaLogBox, {'style':'position: absolute; right: 175px; bottom: 50px; font-size: 11px; font-weight: 100;color: #666666;'}).appendChild(document.createTextNode('Nxt Lvl In:'));

  makeElement('div', mafiaLogBox, {'id':'expToNext', 'style':'position: absolute; right: 141px; bottom: 50px; font-size: 11px; font-weight: 600;color: #04B4AE;'}).appendChild(document.createTextNode(makeCommaValue(ptsToNextLevel)));

  makeElement('div', mafiaLogBox, {'style':'position: absolute; right: 36px; bottom: 50px; font-size: 11px; font-weight: 100;color: #666666;'}).appendChild(document.createTextNode('Stam Req\'d to Lvl:'));

  var stamToNext = (ptsToNextLevel / (GM_getValue('totalExpInt', 0) / ((GM_getValue('fightWinCountInt', 0) + GM_getValue('fightLossCountInt', 0)) + (GM_getValue('robWinCountInt', 0) + GM_getValue('robLossCountInt', 0))))).toFixed(0);
    makeElement('div', mafiaLogBox, {'id':'stamToNext', 'style':'position: absolute; right: 2px; bottom: 50px; font-size: 11px; font-weight: 600;color: #04B4AE;'}).appendChild(document.createTextNode((isNaN(stamToNext)) ? 0 : stamToNext));
}

function createMenu() {

  makeElement('style', document.getElementsByTagName('head')[0], {'type':'text/css'}).appendChild(document.createTextNode(
    '#settingsBox #tabNav div{border-right:1px solid #000;float:left;padding:0 7px;position:static;text-align:center}' +
    '#settingsBox #tabNav div.selected{background-image:url(' + stripURI(tabSelectedImage) + ')}' +
    '#settingsBox #tabNav div a{color:#fff;font-weight:700}' +
    '#settingsBox .sexy_button{position:absolute;background-image:url(http://mwdirectfb10.static.zynga.com/mwfb/graphics/button_static.gif);border:1px solid #FFD927;color:#FFD927;cursor:pointer;display:block;float:left;font-size:14px;font-weight:700;padding:5px;text-decoration:none;width:auto}' +
    '#settingsBox .sexy_button button{background:transparent;border:medium none #FFF;color:#FFD927;cursor:pointer;font-size:14px;font-weight:700;margin:0}' +
    '#settingsBox .sexy_button button:hover{color:#BCD2EA;font-weight:700;text-decoration:none}' +
    '#settingsBox .tabcontent{display:none;height:420px;top:110px;width:600px}' +
    '#settingsBox div,#settingsBox select,#settingsBox textarea{position:absolute}' +
    '#settingsBox label {font-weight: normal; color: #BCD2EA}'
  ));
  // trying to make settings box appear like popup in MW
  // This will fade the background when the settings box is up, just like facebook popups
  makeElement('div', document.body, {'style':'height: 100%; position: fixed; display:block; left:0; top:0; width:100%; z-index:100;', 'class':'dark_dialog_overlay', 'id':'settingsBoxBg'});

  // This creates the settings box just like a facebook popup
  var sBoxGenDialogPopDialog = makeElement('div', document.body, {'class':'generic_dialog pop_dialog', 'id':'GenDialogPopDialog'});
    var sBoxGenDialogPopup = makeElement('div', sBoxGenDialogPopDialog, {'class':'generic_dialog_popup', 'style':'top: 40px;'});
      var sBoxPopDialogTable = makeElement('table', sBoxGenDialogPopup, {'class':'pop_dialog_table', 'id':'pop_dialog_table', 'style':'width: 620px;'});
        var sBoxTableTR = makeElement('tr', sBoxPopDialogTable);
          makeElement('td', sBoxTableTR, {'class':'pop_topleft'});
          makeElement('td', sBoxTableTR, {'class':'pop_border pop_top'});
          makeElement('td', sBoxTableTR, {'class':'pop_topright'});
        var sBoxTableTR2 = makeElement('tr', sBoxPopDialogTable);
          makeElement('td', sBoxTableTR2, {'class':'pop_border pop_side'});
          var sBoxTDPopContent = makeElement('td', sBoxTableTR2, {'class':'pop_content', 'id':'pop_content'});
            // This creates the settings container
            var settingsBox = makeElement('div', sBoxTDPopContent, {'style':'position: relative; width: 600px; height: 580px; font-size: 14px; color: #BCD2EA; background: #000 url(http://mwdirectfb10.static.zynga.com/mwfb/graphics/MW_FB_Background_760.gif) no-repeat scroll 0 110px', 'id':'settingsBox'});
          makeElement('td', sBoxTableTR2, {'class':'pop_border pop_side'});
        var sBoxTableTR3 = makeElement('tr', sBoxPopDialogTable, {'id':'pop_tr3'});
          makeElement('td', sBoxTableTR3, {'class':'pop_bottomleft'});
          makeElement('td', sBoxTableTR3, {'class':'pop_border pop_bottom'});
          makeElement('td', sBoxTableTR3, {'class':'pop_bottomright'});
  //End settings box

  var settingsBoxTopBG = makeElement('div', settingsBox, {'style':'background-image: url('+stripURI(settingsBoxBackgroundImage)+'); position: static; height: 80px;'});

    var settingsBoxTitle = makeElement('div', settingsBoxTopBG, {'style':'font-size: 18px; font-weight: bold;'});
      settingsBoxTitle.appendChild(document.createTextNode('Facebook Mafia Wars Autoplayer'));
      makeElement('br', settingsBoxTitle);
      settingsBoxTitle.appendChild(document.createTextNode('Version '+SCRIPT.version));

    var updateButton = makeElement('span', settingsBoxTopBG, {'class':'sexy_button', 'style':'left: 200px; top: 30px;'});
      makeElement('button', updateButton).appendChild(document.createTextNode('Check for Updates'));
      updateButton.addEventListener('click', updateScript, false);

    makeElement('img', settingsBoxTopBG, {'src':'http://www.zynga.com/images/games/gameSmall_mafiawars.jpg', 'style':'position: absolute; top: 0px; right: 25px;'});

    makeElement('img', settingsBoxTopBG, {'src':stripURI(closeButtonIcon), 'style':'position: absolute; top: 0px; right: 0px; cursor: pointer;'}).addEventListener('click', toggleSettings, false);


  var tabNav = makeElement('div', settingsBox, {'id':'tabNav', 'style':'background: transparent url(http://mwdirectfb10.static.zynga.com/mwfb/graphics/red_bg.gif) repeat-x scroll 0 0; border: 1px solid #FFFFFF; fontsize: 13px; line-height: 28px; top: 80px; height: 30px;'});
    var generalTabLink = makeElement('div', tabNav, {'class':'selected'});
      makeElement('a', generalTabLink, {'href':'#', 'rel':'generalTab'}).appendChild(document.createTextNode('General'));
    var energyTabLink = makeElement('div', tabNav);
      makeElement('a', energyTabLink, {'href':'#', 'rel':'energyTab'}).appendChild(document.createTextNode('Energy'));
    var staminaTabLink = makeElement('div', tabNav);
      makeElement('a', staminaTabLink, {'href':'#', 'rel':'fightRobTab'}).appendChild(document.createTextNode('Fight/Rob'));
    var hitlistTabLink = makeElement('div', tabNav);
      makeElement('a', hitlistTabLink, {'href':'#', 'rel':'hitlistTab'}).appendChild(document.createTextNode('Hitlist'));
    var propertyTabLink = makeElement('div', tabNav);
      makeElement('a', propertyTabLink, {'href':'#', 'rel':'propertyTab'}).appendChild(document.createTextNode('Property'));


  var generalTab = makeElement('div', settingsBox, {'id':'generalTab', 'class':'tabcontent'});

  var autoClick = makeElement('div', generalTab, {'style':'top: 25px;'});
  makeElement('input', autoClick, {'type':'checkbox', 'id':'autoClick', 'value':'checked'}, 'autoClick');
  autoClick.appendChild(document.createTextNode('Enable auto-refresh '));
  makeElement('img', autoClick, {'style':'position: absolute; top: 5px; left: 200px', 'src':stripURI(energyIcon)});

  var refreshTimes = makeElement('div', generalTab, {'style':'left: 20px; top: 50px;'});
  refreshTimes.appendChild(document.createTextNode('Refresh every '));
  makeElement('input', refreshTimes, {'type':'text', 'value':GM_getValue('r1', '30'), 'id':'r1', 'size':'2'});
  refreshTimes.appendChild(document.createTextNode(' to '));
  makeElement('input', refreshTimes, {'type':'text', 'value':GM_getValue('r2', '110'), 'id':'r2', 'size':'2'});
  refreshTimes.appendChild(document.createTextNode(' seconds'));

  var autoHeal = makeElement('div', generalTab, {'style':'top:75px;'});
  makeElement('input', autoHeal, {'type':'checkbox', 'id':'autoHeal', 'value':'checked'}, 'autoHeal', 'checked');
  autoHeal.appendChild(document.createTextNode('Enable auto-heal '));
  makeElement('img', autoHeal, {'src':stripURI(healthIcon)});

  var healthLevel = makeElement('div', generalTab, {'style':'top: 100px; left: 20px;'});
  healthLevel.appendChild(document.createTextNode('Minimum health: '));
  makeElement('input', healthLevel, {'type':'text', 'style':'width: 30px;', 'value':GM_getValue('healthLevel', '50'), 'id':'healthLevel', 'size':'1'});

  elt = makeElement('div', generalTab, {'style':'top: 100px; left: 180px'});
  title = 'Prevent others from being able to attack you by suspending auto-heal below 20 health.';
  id = 'hideInHospital';
  var hideInHospital = makeElement('input', elt, {'type':'checkbox', 'id':id, 'title':title, 'style':'vertical-align:middle', 'value':'checked'}, 'hideInHospital');
  label = makeElement('label', elt, {'for':id, 'title':title});
  label.appendChild(document.createTextNode('Hide in hospital'));
  makeElement('img', elt, {'src':stripURI(hideIcon)});

  var autoBank = makeElement('div', generalTab, {'style':'top: 125px;'});
  makeElement('input', autoBank, {'type':'checkbox', 'id':'autoBank', 'value':'checked'}, 'autoBank');
  autoBank.appendChild(document.createTextNode('Enable auto-bank '));
  makeElement('img', autoBank, {'src':stripURI(bankIcon)});

  var bankConfig = makeElement('div', generalTab, {'style':'top: 150px; left: 20px;'});
  bankConfig.appendChild(document.createTextNode('Minimum deposit: '));
  makeElement('input', bankConfig, {'type':'text', 'style':'width: 80px;', 'value':GM_getValue('bankConfig', '50000'), 'id':'bankConfig', 'size':'5'});
  bankConfig.addEventListener('change', minBankCheck, false);

  var autoPause = makeElement('div', generalTab, {'style':'top: 175px;'});
  makeElement('input', autoPause, {'type':'checkbox', 'id':'autoPause', 'value':'checked'}, 'autoPause');
  autoPause.appendChild(document.createTextNode('Enable auto-pause'));
  autoPause.addEventListener('click', clickAutoPause, false);

  var autoPauseBefore = makeElement('div', generalTab, {'style':'top: 200px; left: 20px;'});
  makeElement('input', autoPauseBefore, {'type':'radio', 'name':'r3', 'id':'autoPauseBefore', 'value':'checked'}, 'autoPauseBefore');
  autoPauseBefore.appendChild(document.createTextNode('Before level up'));

  var autoPauseAfter = makeElement('div', generalTab, {'style':'top: 200px; left: 150px;'});
  makeElement('input', autoPauseAfter, {'type':'radio', 'name':'r3', 'id':'autoPauseAfter', 'value':'checked'}, 'autoPauseAfter');
  autoPauseAfter.appendChild(document.createTextNode('After level up'));

  var autoPauseExp = makeElement('div', generalTab, {'style':'top: 225px; left: 20px;'});
  autoPauseExp.appendChild(document.createTextNode('Experience left to pause at '));
  makeElement('input', autoPauseExp, {'type':'text', 'value':GM_getValue('autoPauseExp', '50'), 'id':'autoPauseExp', 'size':'2'});

  var leftAlign = makeElement('div', generalTab, {'style':'top: 275px;'});
  makeElement('input', leftAlign, {'type':'checkbox', 'id':'leftAlign', 'value':'checked'}, 'leftAlign');
  leftAlign.appendChild(document.createTextNode('Enable left align main frame'));

  var hideAds = makeElement('div', generalTab, {'style':'top: 300px;'});
  makeElement('input', hideAds, {'type':'checkbox', 'id':'hideAds', 'value':'checked'}, 'hideAds');
  hideAds.appendChild(document.createTextNode('Enable hide ads'));

  var autoLog = makeElement('div', generalTab, {'style':'top: 25px; right: 10px;'});
  autoLog.appendChild(document.createTextNode('Enable logging '));
  makeElement('input', autoLog, {'type':'checkbox', 'id':'autoLog', 'value':'checked'}, 'autoLog');

  var logLength = makeElement('div', generalTab, {'style':'top: 50px; right: 10px;'});
  logLength.appendChild(document.createTextNode('Max # of messages in Log '));
  makeElement('input', logLength, {'type':'text', 'id':'autoLogLength', 'value':GM_getValue('autoLogLength', '300'), 'size':'2'});

  var logPlayerUpdates = makeElement('div', generalTab, {'style':'top: 75px; right: 10px;'});
  logPlayerUpdates.appendChild(document.createTextNode('Log Player Updates '));
  makeElement('input', logPlayerUpdates, {'type':'checkbox', 'id':'logPlayerUpdates', 'title':'Send Player Updates to Mafia Log', 'value':'checked'}, 'logPlayerUpdates');

  var autoStats = makeElement('div', generalTab, {'style':' text-align: right; top: 150px; right: 10px;'});
  makeElement('img', autoStats, {'src':stripURI(plussignIcon)});
  autoStats.appendChild(document.createTextNode('Enable auto-stat '));
  makeElement('input', autoStats, {'type':'checkbox', 'id':'autoStat', 'value':'checked'}, 'autoStat');
  autoStats.addEventListener('click', clickStats, false);

  var autoStatAttack = makeElement('div', generalTab, {'style':' top: 175px; right: 200px;'});
  makeElement('input', autoStatAttack, {'type':'radio', 'name':'r2', 'id':'autoStatAttack', 'value':'checked'}, 'autoStatAttack');
  autoStatAttack.appendChild(document.createTextNode('Attack'));

  var autoStatHealth = makeElement('div', generalTab, {'style':' top: 175px; right: 120px;'});
  makeElement('input', autoStatHealth, {'type':'radio', 'name':'r2', 'id':'autoStatHealth', 'value':'checked'}, 'autoStatHealth');
  autoStatHealth.appendChild(document.createTextNode('Health'));

  var autoStatEnergy = makeElement('div', generalTab, {'style':' top: 175px; right: 40px;'});
  makeElement('input', autoStatEnergy, {'type':'radio', 'name':'r2', 'id':'autoStatEnergy', 'value':'checked'}, 'autoStatEnergy');
  autoStatEnergy.appendChild(document.createTextNode('Energy'));

  var autoStatStamina = makeElement('div', generalTab, {'style':' top: 195px; right: 30px;'});
  makeElement('input', autoStatStamina, {'type':'radio', 'name':'r2', 'id':'autoStatStamina', 'value':'checked'}, 'autoStatStamina');
  autoStatStamina.appendChild(document.createTextNode('Stamina'));

  var autoStatDefense = makeElement('div', generalTab, {'style':' top: 195px; right: 110px;'});
  makeElement('input', autoStatDefense, {'type':'radio', 'name':'r2', 'id':'autoStatDefense', 'value':'checked'}, 'autoStatDefense');
  autoStatDefense.appendChild(document.createTextNode('Defense'));

  var delayTimes = makeElement('div', generalTab, {'style':'right: 10px; top: 225px; text-align:right;'});
  delayTimes.appendChild(document.createTextNode('Delay '));
  makeElement('input', delayTimes, {'type':'text', 'value':GM_getValue('d1', '3'), 'id':'d1', 'size':'2'});
  delayTimes.appendChild(document.createTextNode(' to '));
  makeElement('input', delayTimes, {'type':'text', 'value':GM_getValue('d2', '5'), 'id':'d2', 'size':'2'});
  delayTimes.appendChild(document.createTextNode(' seconds'));
  makeElement('br', delayTimes);
  delayTimes.appendChild(document.createTextNode('in-between actions'));


  var energyTab = makeElement('div', settingsBox, {'id':'energyTab', 'class':'tabcontent'});

  var waitForFull = makeElement('div', energyTab, {'style':'top: 25px; right: 10px;'});
  waitForFull.appendChild(document.createTextNode('Wait until energy is full to run jobs'));
  makeElement('input', waitForFull, {'type':'checkbox', 'id':'waitForFull', 'value':'checked'}, 'waitForFull');

  var autoEnergyPack = makeElement('div', energyTab, {'style':' top: 50px; right: 10px;'});
  autoEnergyPack.appendChild(document.createTextNode('Enable auto-energy pack'));
  makeElement('input', autoEnergyPack, {'type':'checkbox', 'id':'autoEnergyPack', 'value':'checked'}, 'autoEnergyPack');

  var estimateJobRatio = makeElement('div', energyTab, {'style':' top: 75px; right: 10px;'});
  estimateJobRatio.appendChild(document.createTextNode('Estimate Job Ratio'));
  makeElement('input', estimateJobRatio, {'type':'text', 'style':'width: 30px;', 'value':GM_getValue('estimateJobRatio', '1'), 'id':'estimateJobRatio', 'size':'2'});

  title = 'Check if you received the helicopter for completing Level 3 mastery of the Consigliere job tab';
  var hasHelicopter = makeElement('div', energyTab, {'style':' top: 100px; right: 10px;'});
  hasHelicopter.appendChild(document.createTextNode('Have helicopter job mastery loot item'));
  makeElement('input', hasHelicopter, {'type':'checkbox', 'id':'hasHelicopter', 'title':title, 'value':'checked'}, 'hasHelicopter');
  
  var autoMission = makeElement('div', energyTab, {'style':' top: 25px;'});
  makeElement('input', autoMission, {'type':'checkbox', 'id':'autoMission', 'value':'checked'}, 'autoMission', 'checked');
  autoMission.appendChild(document.createTextNode('Enable auto-mission '));
  makeElement('img', autoMission, {'src':stripURI(experienceIcon)});

  var selectMission = makeElement('select', energyTab, {'style':'top: 50px; left:5px;', 'id':'selectMission'});
  for each (var mission in missions ) {
    var choice = document.createElement('option');
    if (mission[0] != undefined) {
      choice.value = mission[0];
      choice.appendChild(document.createTextNode(mission[0]));
      selectMission.appendChild(choice);
    }
  }
  selectMission.selectedIndex = GM_getValue('selectMission', 1);

  var repeatJob = makeElement('div', energyTab, {'style':' top: 75px;'});
  makeElement('input', repeatJob, {'type':'checkbox', 'id':'repeatJob', 'value':'checked'}, 'repeatJob');
  repeatJob.appendChild(document.createTextNode('Repeat Job'));

  var selectText = makeElement('div', energyTab, {'style':' left: 20px; top: 100px;'});
  makeElement('img', selectText, {'src':stripURI(energyIcon)});
  selectText.appendChild(document.createTextNode(' Wheelman Energy Savings %'));

  var selectEnergyBonus = makeElement('select', energyTab, {'style':' left: 270px; top: 100px;', 'id':'selectEnergyBonus'});
  for (i=0;i<12;i++) {
    var choice = document.createElement('option');
    choice.value = i;
    choice.appendChild(document.createTextNode(i));
    selectEnergyBonus.appendChild(choice);
  }
  selectEnergyBonus.selectedIndex = (GM_getValue('selectEnergyBonus', 0)>11) ? 0 : GM_getValue('selectEnergyBonus', 0);

  // Create Fight/Rob tab.
  var fightRobTab = createFightRobTab();
  settingsBox.appendChild(fightRobTab);

  // Create Hitlist tab.
  var hitlistTab = createHitlistTab();
  settingsBox.appendChild(hitlistTab);

  // Create Property tab.
  var propertyTab = makeElement('div', settingsBox, {'id':'propertyTab', 'class':'tabcontent'});

  var selectProperties = makeElement('div', propertyTab, {'style':'top: 25px;'});
  selectPropertiesTitle = makeElement('span', selectProperties, {'style':'margin-left:6px;'});
  selectPropertiesTitle.appendChild(document.createTextNode('Select the properties you want to buy:'));
  makeElement('br', selectProperties);
  makeElement('br', selectProperties);
  makeElement('input', selectProperties, {'type':'checkbox', 'id':'abandoned', 'value':'checked'}, 'abandoned', 'checked');
  selectProperties.appendChild(document.createTextNode('Abandoned Lot *'));
  makeElement('br', selectProperties);
  makeElement('input', selectProperties, {'type':'checkbox', 'id':'commercial', 'value':'checked'}, 'commercial', 'checked');
  selectProperties.appendChild(document.createTextNode('Commercial Block *'));
  makeElement('br', selectProperties);
  makeElement('input', selectProperties, {'type':'checkbox', 'id':'downtown', 'value':'checked'}, 'downtown', 'checked');
  selectProperties.appendChild(document.createTextNode('Prime Downtown Lot *'));
  makeElement('br', selectProperties);
  makeElement('input', selectProperties, {'type':'checkbox', 'id':'beachfront', 'value':'checked'}, 'beachfront', 'checked');
  selectProperties.appendChild(document.createTextNode('Beachfront Property *'));
  makeElement('br', selectProperties);
  makeElement('input', selectProperties, {'type':'checkbox', 'id':'mike', 'value':'checked'}, 'mike', 'checked');
  selectProperties.appendChild(document.createTextNode('Mafia Mike\'s *'));
  makeElement('br', selectProperties);
  makeElement('input', selectProperties, {'type':'checkbox', 'id':'rent', 'value':'checked'}, 'rent', 'checked');
  selectProperties.appendChild(document.createTextNode('Rent House *'));
  makeElement('br', selectProperties);
  makeElement('input', selectProperties, {'type':'checkbox', 'id':'restaurant', 'value':'checked'}, 'restaurant');
  selectProperties.appendChild(document.createTextNode('Italian Restaurant'));
  makeElement('br', selectProperties);
  makeElement('input', selectProperties, {'type':'checkbox', 'id':'apartment', 'value':'checked'}, 'apartment');
  selectProperties.appendChild(document.createTextNode('Apartment Complex'));
  makeElement('br', selectProperties);
  makeElement('input', selectProperties, {'type':'checkbox', 'id':'valu', 'value':'checked'}, 'valu');
  selectProperties.appendChild(document.createTextNode('Valu-Mart'));
  makeElement('br', selectProperties);
  makeElement('input', selectProperties, {'type':'checkbox', 'id':'tourist', 'value':'checked'}, 'tourist');
  selectProperties.appendChild(document.createTextNode('Marina Tourist Shops'));
  makeElement('br', selectProperties);
  makeElement('input', selectProperties, {'type':'checkbox', 'id':'office', 'value':'checked'}, 'office');
  selectProperties.appendChild(document.createTextNode('Office Building'));
  makeElement('br', selectProperties);
  makeElement('input', selectProperties, {'type':'checkbox', 'id':'hotel', 'value':'checked'}, 'hotel');
  selectProperties.appendChild(document.createTextNode('5-Star Hotel'));
  makeElement('br', selectProperties);
  makeElement('input', selectProperties, {'type':'checkbox', 'id':'casino', 'value':'checked'}, 'casino');
  selectProperties.appendChild(document.createTextNode('Mega Casino'));
  makeElement('br', selectProperties);
  makeElement('br', selectProperties);
  selectPropertiesNote = makeElement('span', selectProperties, {'style':'margin-left:21px'});
  selectPropertiesNote.appendChild(document.createTextNode('* Properties that cannot be robbed'));

  var autoBuy = makeElement('div', propertyTab, {'style':'top: 25px; right: 10px;'});
  autoBuy.appendChild(document.createTextNode('Enable Auto-buy'));
  makeElement('input', autoBuy, {'type':'checkbox', 'id':'autoBuy', 'value':'checked'}, 'autoBuy');

  var buyMinAmount = makeElement('div', propertyTab, {'style':'top: 50px; right: 10px;'});
  buyMinAmount.appendChild(document.createTextNode('Minimum cash: '));
  makeElement('input', buyMinAmount, {'type':'text', 'style':'width: 80px;', 'value':GM_getValue('buyMinAmount', '0'), 'id':'buyMinAmount', 'size':'5'});

  var autoRepair = makeElement('div', propertyTab, {'style':'top: 100px; right: 10px;'});
  autoRepair.appendChild(document.createTextNode('Enable auto-repair property'));
  makeElement('input', autoRepair, {'type':'checkbox', 'id':'autoRepair', 'value':'checked'}, 'autoRepair');

  var autoProtect = makeElement('div', propertyTab, {'style':'top: 125px; right: 10px;'});
  autoProtect.appendChild(document.createTextNode('Enable auto-protect property'));
  makeElement('input', autoProtect, {'type':'checkbox', 'id':'autoProtect', 'value':'checked'}, 'autoProtect');

  // Create save button
  var saveButton = makeElement('span', settingsBox, {'class':'sexy_button', 'style':'left: 10px; bottom: 10px;'});
  makeElement('button', saveButton).appendChild(document.createTextNode('Save Settings'));
  saveButton.addEventListener('click', saveSettings, false);

//Tab code from:http://www.dynamicdrive.com/dynamicindex17/tabcontent.htm converted into a data URI
  makeElement('script', document.getElementsByTagName('head')[0], {'type':'text/javascript', 'src':
    "data:application/x-javascript;base64,Ly8qKiBUYWIgQ29udGVudCBzY3JpcHQgdjIuMC0gqSBEeW5hbWljIERyaXZlIERIVE1MIGNvZGUgbGlicmFyeSAoaHR0cDovL3d3dy5keW5hbWljZHJpdmUuY29tKQ0KLy8qKiBVcGRhdGVkIE9jdCA3dGgsIDA3IHRvIHZlcnNpb24gMi4wLiBDb250YWlucyBudW1lcm91cyBpbXByb3ZlbWVudHM6DQovLyAgIC1BZGRlZCBBdXRvIE1vZGU6IFNjcmlwdCBhdXRvIHJvdGF0ZXMgdGhlIHRhYnMgYmFzZWQgb24gYW4gaW50ZXJ2YWwsIHVudGlsIGEgdGFiIGlzIGV4cGxpY2l0bHkgc2VsZWN0ZWQNCi8vICAgLUFiaWxpdHkgdG8gZXhwYW5kL2NvbnRyYWN0IGFyYml0cmFyeSBESVZzIG9uIHRoZSBwYWdlIGFzIHRoZSB0YWJiZWQgY29udGVudCBpcyBleHBhbmRlZC8gY29udHJhY3RlZA0KLy8gICAtQWJpbGl0eSB0byBkeW5hbWljYWxseSBzZWxlY3QgYSB0YWIgZWl0aGVyIGJhc2VkIG9uIGl0cyBwb3NpdGlvbiB3aXRoaW4gaXRzIHBlZXJzLCBvciBpdHMgSUQgYXR0cmlidXRlIChnaXZlIHRoZSB0YXJnZXQgdGFiIG9uZSAxc3QpDQovLyAgIC1BYmlsaXR5IHRvIHNldCB3aGVyZSB0aGUgQ1NTIGNsYXNzbmFtZSAic2VsZWN0ZWQiIGdldCBhc3NpZ25lZC0gZWl0aGVyIHRvIHRoZSB0YXJnZXQgdGFiJ3MgbGluayAoIkEiKSwgb3IgaXRzIHBhcmVudCBjb250YWluZXINCi8vKiogVXBkYXRlZCBGZWIgMTh0aCwgMDggdG8gdmVyc2lvbiAyLjE6IEFkZHMgYSAidGFiaW5zdGFuY2UuY3ljbGVpdChkaXIpIiBtZXRob2QgdG8gY3ljbGUgZm9yd2FyZCBvciBiYWNrd2FyZCBiZXR3ZWVuIHRhYnMgZHluYW1pY2FsbHkNCi8vKiogVXBkYXRlZCBBcHJpbCA4dGgsIDA4IHRvIHZlcnNpb24gMi4yOiBBZGRzIHN1cHBvcnQgZm9yIGV4cGFuZGluZyBhIHRhYiB1c2luZyBhIFVSTCBwYXJhbWV0ZXIgKGllOiBodHRwOi8vbXlzaXRlLmNvbS90YWJjb250ZW50Lmh0bT90YWJpbnRlcmZhY2VpZD0wKSANCg0KLy8vL05PIE5FRUQgVE8gRURJVCBCRUxPVy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLw0KDQpmdW5jdGlvbiBkZHRhYmNvbnRlbnQodGFiaW50ZXJmYWNlaWQpew0KCXRoaXMudGFiaW50ZXJmYWNlaWQ9dGFiaW50ZXJmYWNlaWQgLy9JRCBvZiBUYWIgTWVudSBtYWluIGNvbnRhaW5lcg0KCXRoaXMudGFicz1kb2N1bWVudC5nZXRFbGVtZW50QnlJZCh0YWJpbnRlcmZhY2VpZCkuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImEiKSAvL0dldCBhbGwgdGFiIGxpbmtzIHdpdGhpbiBjb250YWluZXINCgl0aGlzLmVuYWJsZXRhYnBlcnNpc3RlbmNlPXRydWUNCgl0aGlzLmhvdHRhYnNwb3NpdGlvbnM9W10gLy9BcnJheSB0byBzdG9yZSBwb3NpdGlvbiBvZiB0YWJzIHRoYXQgaGF2ZSBhICJyZWwiIGF0dHIgZGVmaW5lZCwgcmVsYXRpdmUgdG8gYWxsIHRhYiBsaW5rcywgd2l0aGluIGNvbnRhaW5lcg0KCXRoaXMuY3VycmVudFRhYkluZGV4PTAgLy9JbmRleCBvZiBjdXJyZW50bHkgc2VsZWN0ZWQgaG90IHRhYiAodGFiIHdpdGggc3ViIGNvbnRlbnQpIHdpdGhpbiBob3R0YWJzcG9zaXRpb25zW10gYXJyYXkNCgl0aGlzLnN1YmNvbnRlbnRpZHM9W10gLy9BcnJheSB0byBzdG9yZSBpZHMgb2YgdGhlIHN1YiBjb250ZW50cyAoInJlbCIgYXR0ciB2YWx1ZXMpDQoJdGhpcy5yZXZjb250ZW50aWRzPVtdIC8vQXJyYXkgdG8gc3RvcmUgaWRzIG9mIGFyYml0cmFyeSBjb250ZW50cyB0byBleHBhbmQvY29udGFjdCBhcyB3ZWxsICgicmV2IiBhdHRyIHZhbHVlcykNCgl0aGlzLnNlbGVjdGVkQ2xhc3NUYXJnZXQ9ImxpbmsiIC8va2V5d29yZCB0byBpbmRpY2F0ZSB3aGljaCB0YXJnZXQgZWxlbWVudCB0byBhc3NpZ24gInNlbGVjdGVkIiBDU1MgY2xhc3MgKCJsaW5rcGFyZW50IiBvciAibGluayIpDQp9DQoNCmRkdGFiY29udGVudC5nZXRDb29raWU9ZnVuY3Rpb24oTmFtZSl7IA0KCXZhciByZT1uZXcgUmVnRXhwKE5hbWUrIj1bXjtdKyIsICJpIik7IC8vY29uc3RydWN0IFJFIHRvIHNlYXJjaCBmb3IgdGFyZ2V0IG5hbWUvdmFsdWUgcGFpcg0KCWlmIChkb2N1bWVudC5jb29raWUubWF0Y2gocmUpKSAvL2lmIGNvb2tpZSBmb3VuZA0KCQlyZXR1cm4gZG9jdW1lbnQuY29va2llLm1hdGNoKHJlKVswXS5zcGxpdCgiPSIpWzFdIC8vcmV0dXJuIGl0cyB2YWx1ZQ0KCXJldHVybiAiIg0KfQ0KDQpkZHRhYmNvbnRlbnQuc2V0Q29va2llPWZ1bmN0aW9uKG5hbWUsIHZhbHVlKXsNCglkb2N1bWVudC5jb29raWUgPSBuYW1lKyI9Iit2YWx1ZSsiO3BhdGg9LyIgLy9jb29raWUgdmFsdWUgaXMgZG9tYWluIHdpZGUgKHBhdGg9LykNCn0NCg0KZGR0YWJjb250ZW50LnByb3RvdHlwZT17DQoNCglleHBhbmRpdDpmdW5jdGlvbih0YWJpZF9vcl9wb3NpdGlvbil7IC8vUFVCTElDIGZ1bmN0aW9uIHRvIHNlbGVjdCBhIHRhYiBlaXRoZXIgYnkgaXRzIElEIG9yIHBvc2l0aW9uKGludCkgd2l0aGluIGl0cyBwZWVycw0KCQl0aGlzLmNhbmNlbGF1dG9ydW4oKSAvL3N0b3AgYXV0byBjeWNsaW5nIG9mIHRhYnMgKGlmIHJ1bm5pbmcpDQoJCXZhciB0YWJyZWY9IiINCgkJdHJ5ew0KCQkJaWYgKHR5cGVvZiB0YWJpZF9vcl9wb3NpdGlvbj09InN0cmluZyIgJiYgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQodGFiaWRfb3JfcG9zaXRpb24pLmdldEF0dHJpYnV0ZSgicmVsIikpIC8vaWYgc3BlY2lmaWVkIHRhYiBjb250YWlucyAicmVsIiBhdHRyDQoJCQkJdGFicmVmPWRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHRhYmlkX29yX3Bvc2l0aW9uKQ0KCQkJZWxzZSBpZiAocGFyc2VJbnQodGFiaWRfb3JfcG9zaXRpb24pIT1OYU4gJiYgdGhpcy50YWJzW3RhYmlkX29yX3Bvc2l0aW9uXS5nZXRBdHRyaWJ1dGUoInJlbCIpKSAvL2lmIHNwZWNpZmllZCB0YWIgY29udGFpbnMgInJlbCIgYXR0cg0KCQkJCXRhYnJlZj10aGlzLnRhYnNbdGFiaWRfb3JfcG9zaXRpb25dDQoJCX0NCgkJY2F0Y2goZXJyKXthbGVydCgiSW52YWxpZCBUYWIgSUQgb3IgcG9zaXRpb24gZW50ZXJlZCEiKX0NCgkJaWYgKHRhYnJlZiE9IiIpIC8vaWYgYSB2YWxpZCB0YWIgaXMgZm91bmQgYmFzZWQgb24gZnVuY3Rpb24gcGFyYW1ldGVyDQoJCQl0aGlzLmV4cGFuZHRhYih0YWJyZWYpIC8vZXhwYW5kIHRoaXMgdGFiDQoJfSwNCg0KCWN5Y2xlaXQ6ZnVuY3Rpb24oZGlyLCBhdXRvcnVuKXsgLy9QVUJMSUMgZnVuY3Rpb24gdG8gbW92ZSBmb3dhcmQgb3IgYmFja3dhcmRzIHRocm91Z2ggZWFjaCBob3QgdGFiICh0YWJpbnN0YW5jZS5jeWNsZWl0KCdmb3dhcmQvYmFjaycpICkNCgkJaWYgKGRpcj09Im5leHQiKXsNCgkJCXZhciBjdXJyZW50VGFiSW5kZXg9KHRoaXMuY3VycmVudFRhYkluZGV4PHRoaXMuaG90dGFic3Bvc2l0aW9ucy5sZW5ndGgtMSk%2FIHRoaXMuY3VycmVudFRhYkluZGV4KzEgOiAwDQoJCX0NCgkJZWxzZSBpZiAoZGlyPT0icHJldiIpew0KCQkJdmFyIGN1cnJlbnRUYWJJbmRleD0odGhpcy5jdXJyZW50VGFiSW5kZXg%2BMCk%2FIHRoaXMuY3VycmVudFRhYkluZGV4LTEgOiB0aGlzLmhvdHRhYnNwb3NpdGlvbnMubGVuZ3RoLTENCgkJfQ0KCQlpZiAodHlwZW9mIGF1dG9ydW49PSJ1bmRlZmluZWQiKSAvL2lmIGN5Y2xlaXQoKSBpcyBiZWluZyBjYWxsZWQgYnkgdXNlciwgdmVyc3VzIGF1dG9ydW4oKSBmdW5jdGlvbg0KCQkJdGhpcy5jYW5jZWxhdXRvcnVuKCkgLy9zdG9wIGF1dG8gY3ljbGluZyBvZiB0YWJzIChpZiBydW5uaW5nKQ0KCQl0aGlzLmV4cGFuZHRhYih0aGlzLnRhYnNbdGhpcy5ob3R0YWJzcG9zaXRpb25zW2N1cnJlbnRUYWJJbmRleF1dKQ0KCX0sDQoNCglzZXRwZXJzaXN0OmZ1bmN0aW9uKGJvb2wpeyAvL1BVQkxJQyBmdW5jdGlvbiB0byB0b2dnbGUgcGVyc2lzdGVuY2UgZmVhdHVyZQ0KCQkJdGhpcy5lbmFibGV0YWJwZXJzaXN0ZW5jZT1ib29sDQoJfSwNCg0KCXNldHNlbGVjdGVkQ2xhc3NUYXJnZXQ6ZnVuY3Rpb24ob2Jqc3RyKXsgLy9QVUJMSUMgZnVuY3Rpb24gdG8gc2V0IHdoaWNoIHRhcmdldCBlbGVtZW50IHRvIGFzc2lnbiAic2VsZWN0ZWQiIENTUyBjbGFzcyAoImxpbmtwYXJlbnQiIG9yICJsaW5rIikNCgkJdGhpcy5zZWxlY3RlZENsYXNzVGFyZ2V0PW9ianN0ciB8fCAibGluayINCgl9LA0KDQoJZ2V0c2VsZWN0ZWRDbGFzc1RhcmdldDpmdW5jdGlvbih0YWJyZWYpeyAvL1JldHVybnMgdGFyZ2V0IGVsZW1lbnQgdG8gYXNzaWduICJzZWxlY3RlZCIgQ1NTIGNsYXNzIHRvDQoJCXJldHVybiAodGhpcy5zZWxlY3RlZENsYXNzVGFyZ2V0PT0oImxpbmtwYXJlbnQiLnRvTG93ZXJDYXNlKCkpKT8gdGFicmVmLnBhcmVudE5vZGUgOiB0YWJyZWYNCgl9LA0KDQoJdXJscGFyYW1zZWxlY3Q6ZnVuY3Rpb24odGFiaW50ZXJmYWNlaWQpew0KCQl2YXIgcmVzdWx0PXdpbmRvdy5sb2NhdGlvbi5zZWFyY2gubWF0Y2gobmV3IFJlZ0V4cCh0YWJpbnRlcmZhY2VpZCsiPShcXGQrKSIsICJpIikpIC8vY2hlY2sgZm9yICI%2FdGFiaW50ZXJmYWNlaWQ9MiIgaW4gVVJMDQoJCXJldHVybiAocmVzdWx0PT1udWxsKT8gbnVsbCA6IHBhcnNlSW50KFJlZ0V4cC4kMSkgLy9yZXR1cm5zIG51bGwgb3IgaW5kZXgsIHdoZXJlIGluZGV4IChpbnQpIGlzIHRoZSBzZWxlY3RlZCB0YWIncyBpbmRleA0KCX0sDQoNCglleHBhbmR0YWI6ZnVuY3Rpb24odGFicmVmKXsNCgkJdmFyIHN1YmNvbnRlbnRpZD10YWJyZWYuZ2V0QXR0cmlidXRlKCJyZWwiKSAvL0dldCBpZCBvZiBzdWJjb250ZW50IHRvIGV4cGFuZA0KCQkvL0dldCAicmV2IiBhdHRyIGFzIGEgc3RyaW5nIG9mIElEcyBpbiB0aGUgZm9ybWF0ICIsam9obixnZW9yZ2UsdHJleSxldGMsIiB0byBlYXNpbHkgc2VhcmNoIHRocm91Z2gNCgkJdmFyIGFzc29jaWF0ZWRyZXZpZHM9KHRhYnJlZi5nZXRBdHRyaWJ1dGUoInJldiIpKT8gIiwiK3RhYnJlZi5nZXRBdHRyaWJ1dGUoInJldiIpLnJlcGxhY2UoL1xzKy8sICIiKSsiLCIgOiAiIg0KCQl0aGlzLmV4cGFuZHN1YmNvbnRlbnQoc3ViY29udGVudGlkKQ0KCQl0aGlzLmV4cGFuZHJldmNvbnRlbnQoYXNzb2NpYXRlZHJldmlkcykNCgkJZm9yICh2YXIgaT0wOyBpPHRoaXMudGFicy5sZW5ndGg7IGkrKyl7IC8vTG9vcCB0aHJvdWdoIGFsbCB0YWJzLCBhbmQgYXNzaWduIG9ubHkgdGhlIHNlbGVjdGVkIHRhYiB0aGUgQ1NTIGNsYXNzICJzZWxlY3RlZCINCgkJCXRoaXMuZ2V0c2VsZWN0ZWRDbGFzc1RhcmdldCh0aGlzLnRhYnNbaV0pLmNsYXNzTmFtZT0odGhpcy50YWJzW2ldLmdldEF0dHJpYnV0ZSgicmVsIik9PXN1YmNvbnRlbnRpZCk%2FICJzZWxlY3RlZCIgOiAiIg0KCQl9DQoJCWlmICh0aGlzLmVuYWJsZXRhYnBlcnNpc3RlbmNlKSAvL2lmIHBlcnNpc3RlbmNlIGVuYWJsZWQsIHNhdmUgc2VsZWN0ZWQgdGFiIHBvc2l0aW9uKGludCkgcmVsYXRpdmUgdG8gaXRzIHBlZXJzDQoJCQlkZHRhYmNvbnRlbnQuc2V0Q29va2llKHRoaXMudGFiaW50ZXJmYWNlaWQsIHRhYnJlZi50YWJwb3NpdGlvbikNCgkJdGhpcy5zZXRjdXJyZW50dGFiaW5kZXgodGFicmVmLnRhYnBvc2l0aW9uKSAvL3JlbWVtYmVyIHBvc2l0aW9uIG9mIHNlbGVjdGVkIHRhYiB3aXRoaW4gaG90dGFic3Bvc2l0aW9uc1tdIGFycmF5DQoJfSwNCg0KCWV4cGFuZHN1YmNvbnRlbnQ6ZnVuY3Rpb24oc3ViY29udGVudGlkKXsNCgkJZm9yICh2YXIgaT0wOyBpPHRoaXMuc3ViY29udGVudGlkcy5sZW5ndGg7IGkrKyl7DQoJCQl2YXIgc3ViY29udGVudD1kb2N1bWVudC5nZXRFbGVtZW50QnlJZCh0aGlzLnN1YmNvbnRlbnRpZHNbaV0pIC8vY2FjaGUgY3VycmVudCBzdWJjb250ZW50IG9iaiAoaW4gZm9yIGxvb3ApDQoJCQlzdWJjb250ZW50LnN0eWxlLmRpc3BsYXk9KHN1YmNvbnRlbnQuaWQ9PXN1YmNvbnRlbnRpZCk%2FICJibG9jayIgOiAibm9uZSIgLy8ic2hvdyIgb3IgaGlkZSBzdWIgY29udGVudCBiYXNlZCBvbiBtYXRjaGluZyBpZCBhdHRyIHZhbHVlDQoJCX0NCgl9LA0KDQoJZXhwYW5kcmV2Y29udGVudDpmdW5jdGlvbihhc3NvY2lhdGVkcmV2aWRzKXsNCgkJdmFyIGFsbHJldmlkcz10aGlzLnJldmNvbnRlbnRpZHMNCgkJZm9yICh2YXIgaT0wOyBpPGFsbHJldmlkcy5sZW5ndGg7IGkrKyl7IC8vTG9vcCB0aHJvdWdoIHJldiBhdHRyaWJ1dGVzIGZvciBhbGwgdGFicyBpbiB0aGlzIHRhYiBpbnRlcmZhY2UNCgkJCS8vaWYgYW55IHZhbHVlcyBzdG9yZWQgd2l0aGluIGFzc29jaWF0ZWRyZXZpZHMgbWF0Y2hlcyBvbmUgd2l0aGluIGFsbHJldmlkcywgZXhwYW5kIHRoYXQgRElWLCBvdGhlcndpc2UsIGNvbnRyYWN0IGl0DQoJCQlkb2N1bWVudC5nZXRFbGVtZW50QnlJZChhbGxyZXZpZHNbaV0pLnN0eWxlLmRpc3BsYXk9KGFzc29jaWF0ZWRyZXZpZHMuaW5kZXhPZigiLCIrYWxscmV2aWRzW2ldKyIsIikhPS0xKT8gImJsb2NrIiA6ICJub25lIg0KCQl9DQoJfSwNCg0KCXNldGN1cnJlbnR0YWJpbmRleDpmdW5jdGlvbih0YWJwb3NpdGlvbil7IC8vc3RvcmUgY3VycmVudCBwb3NpdGlvbiBvZiB0YWIgKHdpdGhpbiBob3R0YWJzcG9zaXRpb25zW10gYXJyYXkpDQoJCWZvciAodmFyIGk9MDsgaTx0aGlzLmhvdHRhYnNwb3NpdGlvbnMubGVuZ3RoOyBpKyspew0KCQkJaWYgKHRhYnBvc2l0aW9uPT10aGlzLmhvdHRhYnNwb3NpdGlvbnNbaV0pew0KCQkJCXRoaXMuY3VycmVudFRhYkluZGV4PWkNCgkJCQlicmVhaw0KCQkJfQ0KCQl9DQoJfSwNCg0KCWF1dG9ydW46ZnVuY3Rpb24oKXsgLy9mdW5jdGlvbiB0byBhdXRvIGN5Y2xlIHRocm91Z2ggYW5kIHNlbGVjdCB0YWJzIGJhc2VkIG9uIGEgc2V0IGludGVydmFsDQoJCXRoaXMuY3ljbGVpdCgnbmV4dCcsIHRydWUpDQoJfSwNCg0KCWNhbmNlbGF1dG9ydW46ZnVuY3Rpb24oKXsNCgkJaWYgKHR5cGVvZiB0aGlzLmF1dG9ydW50aW1lciE9InVuZGVmaW5lZCIpDQoJCQljbGVhckludGVydmFsKHRoaXMuYXV0b3J1bnRpbWVyKQ0KCX0sDQoNCglpbml0OmZ1bmN0aW9uKGF1dG9tb2RlcGVyaW9kKXsNCgkJdmFyIHBlcnNpc3RlZHRhYj1kZHRhYmNvbnRlbnQuZ2V0Q29va2llKHRoaXMudGFiaW50ZXJmYWNlaWQpIC8vZ2V0IHBvc2l0aW9uIG9mIHBlcnNpc3RlZCB0YWIgKGFwcGxpY2FibGUgaWYgcGVyc2lzdGVuY2UgaXMgZW5hYmxlZCkNCgkJdmFyIHNlbGVjdGVkdGFiPS0xIC8vQ3VycmVudGx5IHNlbGVjdGVkIHRhYiBpbmRleCAoLTEgbWVhbmluZyBub25lKQ0KCQl2YXIgc2VsZWN0ZWR0YWJmcm9tdXJsPXRoaXMudXJscGFyYW1zZWxlY3QodGhpcy50YWJpbnRlcmZhY2VpZCkgLy9yZXR1cm5zIG51bGwgb3IgaW5kZXggZnJvbTogdGFiY29udGVudC5odG0%2FdGFiaW50ZXJmYWNlaWQ9aW5kZXgNCgkJdGhpcy5hdXRvbW9kZXBlcmlvZD1hdXRvbW9kZXBlcmlvZCB8fCAwDQoJCWZvciAodmFyIGk9MDsgaTx0aGlzLnRhYnMubGVuZ3RoOyBpKyspew0KCQkJdGhpcy50YWJzW2ldLnRhYnBvc2l0aW9uPWkgLy9yZW1lbWJlciBwb3NpdGlvbiBvZiB0YWIgcmVsYXRpdmUgdG8gaXRzIHBlZXJzDQoJCQlpZiAodGhpcy50YWJzW2ldLmdldEF0dHJpYnV0ZSgicmVsIikpew0KCQkJCXZhciB0YWJpbnN0YW5jZT10aGlzDQoJCQkJdGhpcy5ob3R0YWJzcG9zaXRpb25zW3RoaXMuaG90dGFic3Bvc2l0aW9ucy5sZW5ndGhdPWkgLy9zdG9yZSBwb3NpdGlvbiBvZiAiaG90IiB0YWIgKCJyZWwiIGF0dHIgZGVmaW5lZCkgcmVsYXRpdmUgdG8gaXRzIHBlZXJzDQoJCQkJdGhpcy5zdWJjb250ZW50aWRzW3RoaXMuc3ViY29udGVudGlkcy5sZW5ndGhdPXRoaXMudGFic1tpXS5nZXRBdHRyaWJ1dGUoInJlbCIpIC8vc3RvcmUgaWQgb2Ygc3ViIGNvbnRlbnQgKCJyZWwiIGF0dHIgdmFsdWUpDQoJCQkJdGhpcy50YWJzW2ldLm9uY2xpY2s9ZnVuY3Rpb24oKXsNCgkJCQkJdGFiaW5zdGFuY2UuZXhwYW5kdGFiKHRoaXMpDQoJCQkJCXRhYmluc3RhbmNlLmNhbmNlbGF1dG9ydW4oKSAvL3N0b3AgYXV0byBjeWNsaW5nIG9mIHRhYnMgKGlmIHJ1bm5pbmcpDQoJCQkJCXJldHVybiBmYWxzZQ0KCQkJCX0NCgkJCQlpZiAodGhpcy50YWJzW2ldLmdldEF0dHJpYnV0ZSgicmV2IikpeyAvL2lmICJyZXYiIGF0dHIgZGVmaW5lZCwgc3RvcmUgZWFjaCB2YWx1ZSB3aXRoaW4gInJldiIgYXMgYW4gYXJyYXkgZWxlbWVudA0KCQkJCQl0aGlzLnJldmNvbnRlbnRpZHM9dGhpcy5yZXZjb250ZW50aWRzLmNvbmNhdCh0aGlzLnRhYnNbaV0uZ2V0QXR0cmlidXRlKCJyZXYiKS5zcGxpdCgvXHMqLFxzKi8pKQ0KCQkJCX0NCgkJCQlpZiAoc2VsZWN0ZWR0YWJmcm9tdXJsPT1pIHx8IHRoaXMuZW5hYmxldGFicGVyc2lzdGVuY2UgJiYgc2VsZWN0ZWR0YWI9PS0xICYmIHBhcnNlSW50KHBlcnNpc3RlZHRhYik9PWkgfHwgIXRoaXMuZW5hYmxldGFicGVyc2lzdGVuY2UgJiYgc2VsZWN0ZWR0YWI9PS0xICYmIHRoaXMuZ2V0c2VsZWN0ZWRDbGFzc1RhcmdldCh0aGlzLnRhYnNbaV0pLmNsYXNzTmFtZT09InNlbGVjdGVkIil7DQoJCQkJCXNlbGVjdGVkdGFiPWkgLy9TZWxlY3RlZCB0YWIgaW5kZXgsIGlmIGZvdW5kDQoJCQkJfQ0KCQkJfQ0KCQl9IC8vRU5EIGZvciBsb29wDQoJCWlmIChzZWxlY3RlZHRhYiE9LTEpIC8vaWYgYSB2YWxpZCBkZWZhdWx0IHNlbGVjdGVkIHRhYiBpbmRleCBpcyBmb3VuZA0KCQkJdGhpcy5leHBhbmR0YWIodGhpcy50YWJzW3NlbGVjdGVkdGFiXSkgLy9leHBhbmQgc2VsZWN0ZWQgdGFiIChlaXRoZXIgZnJvbSBVUkwgcGFyYW1ldGVyLCBwZXJzaXN0ZW50IGZlYXR1cmUsIG9yIGNsYXNzPSJzZWxlY3RlZCIgY2xhc3MpDQoJCWVsc2UgLy9pZiBubyB2YWxpZCBkZWZhdWx0IHNlbGVjdGVkIGluZGV4IGZvdW5kDQoJCQl0aGlzLmV4cGFuZHRhYih0aGlzLnRhYnNbdGhpcy5ob3R0YWJzcG9zaXRpb25zWzBdXSkgLy9KdXN0IHNlbGVjdCBmaXJzdCB0YWIgdGhhdCBjb250YWlucyBhICJyZWwiIGF0dHINCgkJaWYgKHBhcnNlSW50KHRoaXMuYXV0b21vZGVwZXJpb2QpPjUwMCAmJiB0aGlzLmhvdHRhYnNwb3NpdGlvbnMubGVuZ3RoPjEpew0KCQkJdGhpcy5hdXRvcnVudGltZXI9c2V0SW50ZXJ2YWwoZnVuY3Rpb24oKXt0YWJpbnN0YW5jZS5hdXRvcnVuKCl9LCB0aGlzLmF1dG9tb2RlcGVyaW9kKQ0KCQl9DQoJfSAvL0VORCBpbnQoKSBmdW5jdGlvbg0KDQp9IC8vRU5EIFByb3RvdHlwZSBhc3NpZ25tZW50"
  }).appendChild(document.createTextNode(
    '/***********************************************\n' +
    '* Tab Content script v2.2- © Dynamic Drive DHTML code library (www.dynamicdrive.com)\n' +
    '* This notice MUST stay intact for legal use\n' +
    '* Visit Dynamic Drive at http://www.dynamicdrive.com/ for full source code\n' +
    '***********************************************/\n'
  ));
  makeElement('script', document.getElementsByTagName('head')[0], {'type':'text/javascript'}).appendChild(document.createTextNode(
    'var tabs=new ddtabcontent("tabNav"); //enter ID of Tab Container\n' +
    'tabs.setpersist(true); //toogle persistence of the tabs\' state\n' +
    'tabs.setselectedClassTarget("linkparent"); //"link" or "linkparent"\n' +
    'tabs.init();'
  ));


  DEBUG('Menu created.');
}

function createFightRobTab() {
  var elt, title, id, label;
  var eltStack = [];
  var fightRobTab = makeElement('div', null, {'id':'fightRobTab', 'class':'tabcontent'});

  //
  // First column of options.
  //
  elt = makeElement('div', fightRobTab,
                    {'style':'position: relative; top: 25px; margin-right: 20px; width: 300px; line-height:150%; float: left'});
  title = 'Fight opponents automatically.';
  id = 'autoFight';
  var autoFightCheckbox = makeElement('input', elt, {'type':'checkbox', 'id':id, 'title':title, 'style':'vertical-align:middle', 'value':'checked'}, 'autoFight');
  label = makeElement('label', elt, {'for':id, 'title':title});
  label.appendChild(document.createTextNode('Enable auto-fight'));
  autoFightCheckbox.addEventListener('click', clickFight, false);

  title = 'Rob opponents automatically.';
  id = 'autoRob';
  var autoRobCheckbox = makeElement('input', elt, {'type':'checkbox', 'id':id, 'title':title, 'style':'vertical-align:middle', 'value':'checked'}, 'autoRob');
  label = makeElement('label', elt, {'for':id, 'title':title});
  label.appendChild(document.createTextNode('Enable auto-rob'));
  autoRobCheckbox.addEventListener('click', clickRob, false);

  // Begin radio buttons
  eltStack.push(elt);
  elt = makeElement('div', elt, {'style':'position: static; margin-left: 13px'});
  title = 'Pick opponents from the random lists supplied by Mafia Wars.';
  id = 'fightRandom';
  label = makeElement('label', elt, {'for':id, 'title':title});
  makeElement('input', label, {'type':'radio', 'name':'r1', 'id':id, 'title':title, 'style':'vertical-align:top', 'value':'checked'}, 'fightRandom');
  label.appendChild(document.createTextNode('Fight/Rob random mafia'));

  // Begin options specific to random mafia
  eltStack.push(elt);
  elt = makeElement('div', elt, {'style':'position: static; margin-left: 22px'});
  title = 'Avoid opponents higher than this level.';
  id = 'fightLevel';
  label = makeElement('label', elt, {'for':id, 'title':title, 'style':'width: 9em; float: left; margin-right: 0.5em; display: block'});
  label.appendChild(document.createTextNode('Maximum level:'));
  makeElement('input', elt, {'type':'text', 'id':id, 'title':title, 'style':'width: 30px; border: 1px solid #781351', 'value':GM_getValue('fightLevel', '100'), 'size':'1'});

  title = 'Make the maximum level be relative to your own. For example, if your level is 10, and maximum level is set to 5, opponents higher than level 15 will be avoided.';
  id = 'fightLevelRelative';
  makeElement('input', elt, {'type':'checkbox', 'id':id, 'title':title, 'style':'vertical-align: middle', 'value':'checked'}, 'fightLevelRelative');
  label = makeElement('label', elt, {'for':id, 'title':title});
  label.appendChild(document.createTextNode('Relative'));

  makeElement('br', elt);
  id = 'fightmafiaSize';
  title = 'Avoid opponents with mafia sizes larger than this.',
  label = makeElement('label', elt, {'for':id, 'title':title, 'style':'width: 9em; float: left; margin-right: 0.5em; display: block'});
  label.appendChild(document.createTextNode('Maximum mafia:'));
  makeElement('input', elt, {'type':'text', 'id':id, 'title':title, 'style':'width: 30px; border: 1px solid #781351', 'value':GM_getValue('fightmafiaSize', '502'), 'size':'1'});

  title = 'Make the maximum mafia size be relative to your own. For example, if you have 300 mafia members, and maximum mafia is set to 50, opponents with more than 350 mafia members will be avoided.';
  id = 'fightMafiaRelative';
  makeElement('input', elt, {'type':'checkbox', 'id':id, 'title':title, 'style':'vertical-align: middle', 'value':'checked'}, 'fightMafiaRelative');
  label = makeElement('label', elt, {'for':id, 'title':title});
  label.appendChild(document.createTextNode('Relative'));

  makeElement('br', elt);
  id = 'fightmafiaMinSize';
  title = 'Avoid opponents with mafia sizes smaller than this.',
  label = makeElement('label', elt, {'for':id, 'title':title, 'style':'width: 9em; float: left; margin-right: 0.5em; display: block'});
  label.appendChild(document.createTextNode('Minimum mafia:'));
  makeElement('input', elt, {'type':'text', 'id':id, 'title':title, 'style':'width: 30px; border: 1px solid #781351', 'value':GM_getValue('fightmafiaMinSize', '1'), 'size':'1'});

  title = 'Make the minimum mafia size be relative to your own. For example, if you have 300 mafia members, and minimum mafia is set to 50, opponents with less than 250 mafia members will be avoided.';
  id = 'fightMafiaMinRelative';
  makeElement('input', elt, {'type':'checkbox', 'id':id, 'title':title, 'style':'vertical-align: middle', 'value':'checked'}, 'fightMafiaMinRelative');
  label = makeElement('label', elt, {'for':id, 'title':title});
  label.appendChild(document.createTextNode('Relative'));
  makeElement('br', elt);
  title = 'Prefer opponents who won\'t be notified of your attacks.';
  id = 'fightStealth';
  makeElement('input', elt, {'type':'checkbox', 'id':id, 'title':title, 'style':'vertical-align:middle', 'value':'checked'}, 'fightStealth', 'checked');
  label = makeElement('label', elt, {'for':id, 'title':title});
  label.appendChild(document.createTextNode('Use fight stealth'));

  makeElement('br', elt);
  title = 'Avoid opponents known to be Top Mafia bodyguards. This may ' +
          'decrease the frequency of losses due to critical hits.';
  id = 'fightAvoidBodyguards';
  makeElement('input', elt, {'type':'checkbox', 'id':id, 'title':title, 'style':'vertical-align:middle', 'value':'checked'}, 'fightAvoidBodyguards', 'checked');
  label = makeElement('label', elt, {'for':id, 'title':title});
  label.appendChild(document.createTextNode('Avoid Top Mafia bodyguards'));
  // Finish options specific to random mafia
  elt = eltStack.pop();

  title = 'Use a custom list of opponents. Enter each opponent\'s ID' +
          ' (not their name) on a separate line.';
  id = 'rFightList';
  label = makeElement('label', elt, {'for':id, 'title':title});
  makeElement('input', label, {'type':'radio', 'name':'r1', 'id':id, 'title':title, 'style':'vertical-align:top', 'value':'checked'}, 'rFightList');
  label.appendChild(document.createTextNode('Fight/Rob list'));

  // Begin options specific to opponent list
  eltStack.push(elt);
  elt = makeElement('div', elt, {'style':'position: static; margin-left: 22px'});
  makeElement('textarea', elt, {'style':'position: static; width: 180px; height: 105px;', 'id':'fightList', 'title':'Enter each opponent\'s ID (not their name) on a separate line.'}).appendChild(document.createTextNode(GM_getValue('fightList', '')));
  // Finish options specific to opponent list
  elt = eltStack.pop();

  // End of radio buttons
  makeElement('br', elt);
  elt = eltStack.pop();

  //Stamina preservation options
  title = 'Suspend automatic play below this level of stamina.';
  id = 'selectStaminaKeep';
  label = makeElement('label', elt, {'for':id, 'title':title, 'style':'width: 17em; float: left; margin-left: 6px; margin-right: 0.5em; display: block'});
  label.appendChild(document.createTextNode('% Stamina to keep on hand (±1)'));
  var selectStaminaKeep = makeElement('select', elt, {'id':id, 'title':title});
  for (i=100;i>-1;i=i-10) {
    var choice = document.createElement('option');
    choice.value = i;
    choice.appendChild(document.createTextNode(i));
    selectStaminaKeep.appendChild(choice);
  }
  if (GM_getValue('selectStaminaKeep', 'NotSet') == 'NotSet' || GM_getValue('selectStaminaKeep', 0) > selectStaminaKeep.length - 1) {
    GM_setValue('selectStaminaKeep', selectStaminaKeep.length - 1);
  }
  selectStaminaKeep.selectedIndex = GM_getValue('selectStaminaKeep', 0);

  makeElement('br', elt);
  title = 'Ignore minimum stamina settings if a level up is within reach.';
  id = 'allowStaminaToLevelUp';
  makeElement('input', elt, {'type':'checkbox', 'id':id, 'title':title, 'style':'vertical-align: middle', 'value':'checked'}, 'allowStaminaToLevelUp');
  label = makeElement('label', elt, {'for':id, 'title':title});
  label.appendChild(document.createTextNode('Use all stamina to level up'));


  //
  // Second column of options.
  //
  elt = makeElement('div', fightRobTab, {'style':'position: relative; float: left; top: 159px;'});

  // Clan names.
  title = 'Avoid random opponents whose names contain specific patterns.';
  id = 'clanMember';
  makeElement('input', elt, {'type':'checkbox', 'id':id, 'title':title, 'style':'vertical-align:middle', 'value':'checked'}, 'clanMember', 0);
  label = makeElement('label', elt, {'for':id, 'title':title});
  label.appendChild(document.createTextNode('Avoid mafia families '));
  makeElement('img', label, {'src':stripURI(mafiaHatIcon)});
  makeElement('br', elt);
  eltStack.push(elt);
  elt = makeElement('div', elt, {'style':'position: static; margin-left: 22px'});
  makeElement('textarea', elt, {'style':'position: static; width: 180px; height: 105px;', 'id':'clanName', 'title':'Enter each pattern (such as a clan name) on a separate line.'}).appendChild(document.createTextNode(GM_getValue('clanName', defaultClans.join('\n'))));;
  makeElement('br', elt);
  elt = eltStack.pop();

  return fightRobTab;
}

function createHitlistTab() {
  var elt, title, id, label;
  var eltStack = [];
  var hitlistTab = makeElement('div', null, {'id':'hitlistTab', 'class':'tabcontent'});

  //
  // First column of options.
  //
  elt = makeElement('div', hitlistTab,
                    {'style':'top: 25px; text-decoration: line-through;'});
  title = 'Keep Players on Hitlist.';
  id = 'autoHitlist';
  var autoHitlistCheckbox = makeElement('input', elt, {'type':'checkbox', 'id':id, 'title':title, 'style':'vertical-align:middle', 'value':'checked'}, 'autoHitlist');
  label = makeElement('label', elt, {'for':id, 'title':title});
  label.appendChild(document.createTextNode('Enable auto-hitlist '));

  elt = makeElement('div', elt, {'style':'position: static; margin-left: 13px'});
  title = 'Use a custom list of opponents. Enter each opponent\'s ID' +
          ' (not their name) on a separate line.';
  id = 'toHitlist';
  makeElement('textarea', elt, {'style':'position: static; width: 180px; height: 105px;', 'id':id, 'title':title}).appendChild(document.createTextNode(GM_getValue(id, '')));

  elt = makeElement('div', hitlistTab,
                    {'style':'top: 175px;'});
  title = 'Only Show Summary of Attacks.';
  id = 'hideAttacks';
  var hideAttacksCheckbox = makeElement('input', elt, {'type':'checkbox', 'id':id, 'title':title, 'value':'checked'}, 'hideAttacks');
  label = makeElement('label', elt, {'for':id, 'title':title});
  label.appendChild(document.createTextNode('Summarize Attacks From Player Updates '));

  //second column of Hitlist Tab
  elt = makeElement('div', hitlistTab, {'style':'top: 25px; right: 10px; text-decoration: line-through;'});
  title = 'This will be the bounty amount for all auto-hitlists.';
  id = 'bountyAmount';
  label = makeElement('label', elt, {'for':id, 'title':title});
  label.appendChild(document.createTextNode('Bounty Amount: '));
  var bountyAmountCheckbox = makeElement('input', elt, {'type':'text', 'style':'width: 80px;', 'title':title, 'value':GM_getValue(id, '10000'), 'id':id, 'size':'1'});

  makeElement('br', elt);
  title = 'Clear AutoPlayer Hitlist Memory';
  id = 'clrHitlistArray';
  var clearHitlistButton = makeElement('span', elt, {'class':'sexy_button', 'title':title});
  makeElement('button', clearHitlistButton).appendChild(document.createTextNode('Clear hitList Array'));
  clearHitlistButton.addEventListener('click', clearHitlistArray, false);

  return hitlistTab;
}

function makeElement(type, appendto, attributes, checked, chkdefault) {
  var element = document.createElement(type);
  if (attributes != null) {
    for (var i in attributes) {
      element.setAttribute(i, attributes[i]);
    }
  }
  if (checked != null) {
    if (GM_getValue(checked, chkdefault) == 'checked') {
      element.setAttribute('checked', 'checked');
    }
  }
  if (appendto) {
    appendto.appendChild(element);
  }
  return element;
}

function stripURI(img) {
  img = img.split('"')[1];
  return img.replace('" />', '');
}

function xpath(query, element) {
  var element = (element == null) ? document : element;
  return document.evaluate(query, element, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
}

function clickFight() {
  if (this.checked)
    // Turn off auto-rob.
    document.getElementById('autoRob').checked = false;
  if (!document.getElementById('rFightList').checked){
    document.getElementById('fightRandom').checked = true;
  }
}

function clickRob() {
  if (this.checked)
    // Turn off auto-fight.
    document.getElementById('autoFight').checked = false;
  if (!document.getElementById('rFightList').checked){
    document.getElementById('fightRandom').checked = true;
  }
}

function clickStats() {
  if (this.checked) {
    // check to ensure at least one radio box is checked
    // enable energy by default
    if (document.getElementById('autoStatAttack').checked === false && document.getElementById('autoStatDefense').checked === false &&
        document.getElementById('autoStatEnergy').checked === false && document.getElementById('autoStatHealth').checked === false &&
        document.getElementById('autoStatStamina').checked === false) {
      document.getElementById('autoStatEnergy').checked = true;
    }
  }
}

function clickAutoPause() {
  if (this.checked) {
    // check to ensure at least one radio box is checked
    // enable Before level up by default
    if (document.getElementById('autoPauseBefore').checked === false &&
        document.getElementById('autoPauseAfter').checked === false) {
      document.getElementById('autoPauseBefore').checked = true;
    }
  }
}

function $x(p,c) {
  var i, r = [], x=document.evaluate(p, c || document, null, XPathResult.UNORDERED_NODE_ITERATOR_TYPE, null);
  while (i=x.iterateNext()) r.push(i);
  return r;
}

window.addEventListener( 'load', function( e ) {

  if (document.body.innerHTML.indexOf('Try Again')>=0) {
    // error
    window.setTimeout(function() {
      window.history.go(0);
    }, 2*60*1000);
    DEBUG('Reloading from Try Again error.');
    return;
  }
},false);

function nodeInserted(e) {
  if (!document.getElementById('autoPlay') &&
      document.getElementById(SCRIPT.appID + '_mw_masthead')) {
    try {
      refreshGlobalStats();
      refreshSettings();
      customizeMasthead();
      customizeStats();
      customizeProfile();
      customizeJobs();

      // Property
      if (document.getElementById(SCRIPT.appID+'_property')) {
        propertyGet();
      }

      // Profile
      //FIXME: Combine this code with customizeProfile()
      var currentPageTitle = xpath('//div[@class=\'tab_content\']');
      currentPageTitle = (currentPageTitle.snapshotLength > 0) ? currentPageTitle.snapshotItem(0).innerHTML : '';
      if (currentPageTitle.indexOf('Profile') != -1) {
        profileFix();
      }

      // Kick off auto-play.
      doAutoPlay();
    } catch(ex) {
      DEBUG(ex);
    }
  }

  // Check for a change in a particular statistic. This is where we'll
  // notice some types of changes that happen without user or script
  // actions, such as earning energy.
  var parentElt = e.target.parentNode;
  if (parentElt == energyElt) {
    energy = parseInt(e.target.nodeValue);
    energyElt.style.textDecoration = (energy == maxEnergy)? 'blink' : 'none';
    setLevelUpRatio();
  } else if (parentElt == staminaElt) {
    stamina = parseInt(e.target.nodeValue);
    staminaElt.style.textDecoration = (stamina == maxStamina)? 'blink' : 'none';
  } else if (parentElt == cashElt) {
    cash = parseInt(e.target.nodeValue.replace(/[$,]/g, ''));
  } else if (parentElt == healthElt) {
    // NOTE: At one time, health was updated on with a timer. Leave
    //       this here in case it goes back to being that way.
    health = parseInt(e.target.nodeValue);
  }
}

function refreshGlobalStats() {
  // Set all the element globals. They change.
  cashElt = document.getElementById(SCRIPT.appID+'_user_cash');
  if (!cashElt) {
    return false;
  }
  healthElt = document.getElementById(SCRIPT.appID+'_user_health');
  energyElt = document.getElementById(SCRIPT.appID+'_user_energy');
  maxEnergyElt = document.getElementById(SCRIPT.appID+'_user_max_energy');
  staminaElt = document.getElementById(SCRIPT.appID+'_user_stamina');
  maxStaminaElt = document.getElementById(SCRIPT.appID+'_user_max_stamina');
  levelElt = document.getElementById(SCRIPT.appID+'_user_level');
  curExpElt = document.getElementById(SCRIPT.appID+'_user_experience');
  lvlExpElt     = document.getElementById(SCRIPT.appID+'_exp_for_next_level');

  // Update basic player information.
  cash = parseInt(cashElt.innerHTML.replace(/[$,]/g, ''));
  health = parseInt(healthElt.innerHTML);
  energy = parseInt(energyElt.firstChild.nodeValue);
  maxEnergy = parseInt(maxEnergyElt.innerHTML);
  stamina = parseInt(staminaElt.firstChild.nodeValue);
  maxStamina = parseInt(maxStaminaElt.innerHTML);
  level = parseInt(levelElt.innerHTML);
  curExp = parseInt(curExpElt.innerHTML);
  lvlExp = parseInt(lvlExpElt.innerHTML);
  ptsToNextLevel = lvlExp - curExp;

  // Get the mafia size and pending invites.
  var mafiaLinks = xpath('//div[@class=\'mafia_link\']/a');
  mafia = mafiaLinks.snapshotItem(1);
  if (mafia) {
    mafia = parseInt(mafia.innerHTML);
  }
  if (!mafia || mafia < 1) {
    addToLog('warning Icon','BUG DETECTED: Unable to read mafia size.');
  }
  invites = mafiaLinks.snapshotItem(2);
  if (invites) {
    invites = invites.innerHTML.split('+')[1];
    if (invites) {
      invites = parseInt(invites);
      if (isNaN(invites)) {
        addToLog('warning Icon','BUG DETECTED: Unable to read invites.');
        invites = 0;
      }
    }
  }
  if (!invites) {
    invites = 0;
  }

  // Get the skill points waiting to be spent.
  var skillElt = xpath('//a[@class=\'alert_number\' and contains(text(),\'+\')]').snapshotItem(0);
  if (skillElt) {
    stats = parseInt(skillElt.innerHTML.split('+')[1]);
    if (isNaN(stats)) {
      stats = 0;
    }
  } else {
    stats = 0;
  }

  // Is an energy pack waiting to be used?
  // NOTE: This will only be accurate when on the home page.
  energyPack = (xpath('//span[@class=\'sexy_pack_use\' and contains(text(),\'Use Energy Pack\')]').snapshotLength > 0);

  // Show congratulations if level has increased.
  if (GM_getValue('currentLevel', 0) < level) {
    GM_setValue('currentLevel', level);
    addToLog('experience Icon', '<font style="color:#00FFCC;"> Congratulations on reaching level <strong>' + level + '</strong>!</font>');
  }

  return true;
}

function refreshSettings() {
  // Determine the minimum stamina to keep on hand.
  staminaFloor = (maxStamina * (1 - parseInt(GM_getValue('selectStaminaKeep', 0)) * .10)).toFixed(0);
  if (staminaFloor >= maxStamina) {
    // Subtract one or else fight/rob will never run.
    staminaFloor--;
  }
  if (staminaFloor == 0 &&
      GM_getValue('autoFight', '') == 'checked' &&
      GM_getValue('fightRandom', '') == 'checked' &&
      GM_getValue('fightStealth', '') == 'checked') {
    // Stealth mode requires 2+ stamina to work properly.
    staminaFloor = 1;
  }

  // Set if auto-burn can be used.
  autoStamBurnif = GM_getValue('allowStaminaToLevelUp', '') == 'checked' && stamina >= (ptsToNextLevel / (GM_getValue('totalExpInt', 0) / ((GM_getValue('fightWinCountInt', 0) + GM_getValue('fightLossCountInt', 0)) + (GM_getValue('robWinCountInt', 0) + GM_getValue('robLossCountInt', 0))))).toFixed(0);
}


function customizeMasthead() {
  var lobjTitleRow = document.getElementById(SCRIPT.appID + '_mw_masthead');

  // Set custom styles with CSS.
  if(!document.getElementById('nodeInsertedCss')) {
    makeElement('style', document.getElementsByTagName('head')[0], {'id':'nodeInsertedCss', 'type':'text/css'}).appendChild(document.createTextNode(
      '#'+SCRIPT.appID+'_mw_masthead span:hover{text-decoration:underline}'+
      '#'+SCRIPT.appID+'_mw_masthead span{position: absolute; left: 320px; font-family: tahoma; font-size: 10pt; font-weight: 600;cursor: pointer; color: rgb(255, 217, 39)}'
    ));
  }

  // Settings Link
  var lobjAutoPlay = makeElement('span', lobjTitleRow, {'id':'autoPlay', 'style':'top: 3px'});
    lobjAutoPlay.appendChild(document.createTextNode('AutoPlay settings'));
    lobjAutoPlay.addEventListener('click', toggleSettings, false);

  // Show resume or paused based on if we are running or not.
  // NOTE: We are checking a string here pulled from the inside of a div
  //       not a bool, so compare it like a string. If we compare like a
  //       bool it will always be true as long as the div contains
  //       something, and it does.
  if (document.getElementById('isRunningStore').firstChild.nodeValue == 'true') {
    var lobjpauseButton = makeElement('span', lobjTitleRow, {'id':'pauseButton', 'style':'top: 18px'});
      lobjpauseButton.appendChild(document.createTextNode('pause'));
      lobjpauseButton.addEventListener('click', pause, false);
  } else {
    var lobjplayButton = makeElement('span', lobjTitleRow, {'style':'top: 18px'});
      lobjplayButton.appendChild(document.createTextNode('resume'));
      lobjplayButton.addEventListener('click', unPause, false);

    makeElement('div', lobjTitleRow, {'style':'background: transparent url(' + stripURI(pausedMessageImage) + ') no-repeat scroll 20px; position: absolute; top: 0; left: 0; bottom: 0; width: 250px'});
  }

  // View log button.
  var lobjViewLogButton = makeElement('span', lobjTitleRow, {'style':'top: 35px'});
    lobjViewLogButton.appendChild(document.createTextNode('view mafia log'));
    lobjViewLogButton.addEventListener('click', showMafiaLogBox, false);
}

function customizeStats() {
  // Make health icon clickable for instant healing.
  var elt = xpath('//img[@alt=\'Health\']').snapshotItem(0);
  if (elt) {
    var link = makeElement('a', null, {'href':'http://apps.facebook.com/' + SCRIPT.name + SCRIPT.controller + 'hospital' + SCRIPT.action + 'heal'})
    elt.parentNode.insertBefore(link, elt);
    link.appendChild(elt);

    // Substitute the "hide" icon if currently hiding in the hospital.
    if (health < 20 && GM_getValue('hideInHospital', '') == 'checked') {
      var hide = makeElement('img', null, {'class':'icon', 'width':'16', 'height':'16', 'src':stripURI(hideIcon)});
      link.replaceChild(hide, elt);
    }
  }

  // Show points until next level.
  elt = xpath('//span[@class=\'stat_title\' and contains(text(),\'Experience\')]').snapshotItem(0);
  if (elt) {
    elt.innerHTML = 'Experience (-' + ptsToNextLevel + ')';
  }

  // Blink maxed out energy or stamina.
  energyElt.style.textDecoration = (energy == maxEnergy)? 'blink' : 'none';
  staminaElt.style.textDecoration = (stamina == maxStamina)? 'blink' : 'none';
}

function customizeProfile() {
  // Extra options for the profile page.
  var statsDiv = xpath('//td[@class=\'stats_left\']/div').snapshotItem(0);
  if (statsDiv) {
    statsDiv.innerHTML.match(/opponent_id=(\d+)/);
    var id = RegExp.lastParen;
    if (id) {
      makeElement('br', statsDiv);
      makeElement('a', statsDiv, {'href':'http://www.facebook.com/profile.php?id=' + id}).appendChild(document.createTextNode('Facebook Profile'));
      statsDiv.appendChild(document.createTextNode(' | '));
      makeElement('a', statsDiv, {'href':'http://www.facebook.com/addfriend.php?id=' + id}).appendChild(document.createTextNode('Add as Friend'));
      statsDiv.appendChild(document.createTextNode(' | '));
      makeElement('a', statsDiv, {'href':'http://apps.facebook.com/' + SCRIPT.name + '/status_invite.php?from=' + id}).appendChild(document.createTextNode('Add to Mafia'));
      statsDiv.appendChild(document.createTextNode(' | '));
      makeElement('a', statsDiv, {'href':'http://apps.facebook.com/' + SCRIPT.name + SCRIPT.controller + 'group' + SCRIPT.action + 'view' + '&promote=yes&uid=' + id}).appendChild(document.createTextNode('Promote'));
      makeElement('br', statsDiv);
      var el = makeElement('a', statsDiv, {'id':id});
      fightList = getSavedList('fightList');
      if (fightList.indexOf(id) != -1) {
        el.appendChild(document.createTextNode('Remove from Fight/Rob List'));
        el.addEventListener('click', clickFightListRemove, false);
      } else {
        el.appendChild(document.createTextNode('Add to Fight/Rob List'));
        el.addEventListener('click', clickFightListAdd, false);
      }
    }
  }
}

function customizeJobs() {
  // Extras for jobs pages.
  var jobTable = xpath('//table[@class=\'job_list\']').snapshotItem(0);
  if (!jobTable) {
    // We're not on a jobs page.
    return;
  }

  // Display an experience to energy payoff ratio for each job.
  var bestJobs = [], worstJobs = [];
  var bestRatio = 0, worstRatio = 10;
  var energies = xpath('//td[@class=\'job_energy\']/span[@class=\'bold_number\']', jobTable);
  var rewards = xpath('//td[@class=\'job_reward\']/span[@class=\'bold_number\']', jobTable);
  var jobButton = xpath('//td[@class=\'job_action\']', jobTable);
  for (var i = 0; i < energies.snapshotLength; i++) {
    elt = energies.snapshotItem(i);
    var cost = parseInt(elt.firstChild.nodeValue);
    var reward = parseInt(rewards.snapshotItem(i).firstChild.nodeValue);
    var ratio = Math.round(reward / cost * 100) / 100;
    makeElement('br', elt.parentNode);
    makeElement('span', elt.parentNode, {'style':'color:#666666; font-size: 11px'}).appendChild(document.createTextNode('Pays ' + ratio + 'x'));

    // Keep track of the best & worst payoffs.
    if (ratio > bestRatio) {
      bestRatio = ratio;
      bestJobs = [elt];
    } else if (ratio == bestRatio) {
      bestJobs.push(elt);
    }
    if (ratio < worstRatio) {
      worstRatio = ratio;
      worstJobs = [elt];
    } else if (ratio == worstRatio) {
      worstJobs.push(elt);
    }
  
    // Calculate time left for each job and display under the do job button
    var timePerEnergy = GM_getValue('hasHelicopter', 0) == 'checked' ? 4.5 : 5;
    if (cost > energy) {
      jobTimeLeft = (cost - energy) * timePerEnergy;
      if (jobTimeLeft < 60)
        jobTimeLeftText = 'Time: < ' + Math.round(jobTimeLeft) + ' min';
      else {
        jobTimeLeft = Math.round((jobTimeLeft/60) * 100) / 100;
        if (jobTimeLeft < 24)
          jobTimeLeftText = 'Time: < ' + jobTimeLeft + ' hr';
        else
          jobTimeLeftText = 'Time: < ' + Math.round(jobTimeLeft/24) + ' days';
      }
    } else {
      jobTimeLeftText = 'Time: 0 min';
    } 
    makeElement('br', jobButton.snapshotItem(i));
    makeElement('span', jobButton.snapshotItem(i), {'style':'color:#666666; font-size: 11px'}).appendChild(document.createTextNode(jobTimeLeftText));
  }

  // Highlight the best and worst jobs.
  if (worstRatio != bestRatio) {
    while (bestJobs.length) {
      elt = bestJobs.pop().parentNode;
      makeElement('br', elt);
      elt = makeElement('span', elt, {'style':'color:#52E259; font-size: 11px'});
      makeElement('img', elt, {'src':stripURI(goodIcon), 'width':'12', 'height':'12', 'style':'vertical-align:middle'});
      elt.appendChild(document.createTextNode(' BEST'));
    }
    while (worstJobs.length) {
      elt = worstJobs.pop().parentNode;
      makeElement('br', elt);
      elt = makeElement('span', elt, {'style':'color:#EC2D2D; font-size: 11px'});
      makeElement('img', elt, {'src':stripURI(badIcon), 'width':'12', 'height':'12', 'style':'vertical-align:middle'});
      elt.appendChild(document.createTextNode(' WORST'));
    }
  }

  // Show the experience to energy ratio needed to level up.
  elt = makeElement('div', null, {'id':'level_up_ratio','style':'text-align:center; display:none'});
  makeElement('img', elt, {'src':stripURI(infoIcon),'style':'vertical-align:middle'});
  elt.appendChild(document.createTextNode(''));
  jobTable.parentNode.insertBefore(elt, jobTable);
  setLevelUpRatio();
}

function setLevelUpRatio() {
  var elt = document.getElementById('level_up_ratio');
  if (elt) {
    if (energy) {
      var ratio = Math.round((lvlExp - curExp) / energy * 100) / 100;
      elt.childNodes[1].nodeValue = ' A ' + (ratio > 10? '>10' : ratio) + 'x pay ratio would be needed to level up on energy alone.';
      elt.style.display = 'block';
    } else {
      elt.style.display = 'none';
    }
  }
}

// Callback for clicking 'Add to Fight/Rob List' on profile page.
function clickFightListAdd() {
  addSavedListItem('fightList', this.id);
  this.firstChild.nodeValue = 'Remove from Fight/Rob List';
  this.removeEventListener('click', clickFightListAdd, false);
  this.addEventListener('click', clickFightListRemove, false);
  var el = document.getElementById('fightList');
  if (el) {
    el.value = GM_getValue('fightList', '');
  }
}

// Callback for clicking 'Remove from Fight/Rob List' on profile page.
function clickFightListRemove() {
  removeSavedListItem('fightList', this.id);
  this.firstChild.nodeValue = 'Add to Fight/Rob List';
  this.removeEventListener('click', clickFightListRemove, false);
  this.addEventListener('click', clickFightListAdd, false);
  var el = document.getElementById('fightList');
  if (el) {
    el.value = GM_getValue('fightList', '');
  }
}

function jobReqs (element) {
  // If we are here then we have already failed the job.
  addToLog('process Icon', 'Getting job requirements.');
  var currentJob = missions[GM_getValue('selectMission', 1)][0];
  // Call for xpath differs based on quoting.
  // WARNING: This won't work if the job name has both double quotes (")
  //          and apostrophes ('). Back to the drawing board if that happens.
  var xQuote = (currentJob.indexOf('"') != -1) ?  '\'' : '"';
  var necessaryItems = $x('//tr[contains(.,' + xQuote + currentJob + xQuote + ')]/td/div[@class=\'req_item need_item\']/a/img', element);
  var necessaryItemsNoLink = $x('//tr[contains(.,' + xQuote + currentJob + xQuote + ')]/td/div[@class=\'req_item need_item\']/img', element);
  var items = getSavedList('itemList');
  var jobs = getSavedList('jobsToDo', '');
  var jobno = missions[GM_getValue('selectMission', 1)][2];
  var tabno = missions[GM_getValue('selectMission', 1)][3];
  var buyElt = xpath('//a[contains(@href, \'buyJob\')]', element).snapshotItem(0);
  if (buyElt) {
    addToLog('search Icon', 'Attempting to purchase required items.');
    Autoplay.fx = function(){ goLinkElement(buyElt); };
  } else {
    // Save the current job for later. The current job should not already
    // exist in the list, so check first.
    DEBUG ('Nothing to buy; moving to prerequisite job.');
    if (jobs.indexOf(currentJob) == -1) {
      jobs.push(currentJob);
      DEBUG('Saving ' + currentJob + ' for later.');
      setSavedList('jobsToDo', jobs);
    } else {
      DEBUG(currentJob + ' is already in the jobs to-do list.');
    }

    if ( necessaryItems.length > 0 ) {
      necessaryItems.forEach(
        function(i){
          DEBUG('Missing : ' +i.alt);
          requirementJob.forEach(
            function(j){
              if(j[0] == i.alt) {
                jobs.push(j[1]);
                items.push(i.alt);
              }
            }
          );
        }
      );
    } else if (necessaryItemsNoLink.length > 0) {
      necessaryItemsNoLink.forEach(
        function(i){
          DEBUG('Missing: ' +i.alt);
          requirementJob.forEach(
            function(j){
              if(j[0] == i.alt) {
                jobs.push(j[1]);
                items.push(i.alt);
              }
            }
          );
        }
      );
    } else { DEBUG('BUG DETECTED: Broken item detection.'); }
    var doJob = jobs.pop();
    setSavedList('jobsToDo', jobs);
    setSavedList('itemList', items.unique());
    var i = 0;
    DEBUG('Will do job ' + doJob + ' next.');

    missions.forEach(
      function(f) {
          // help locate name miss matches
          //DEBUG(f[0] +'  :<<f>>: ' + missions[i][0]);
        if(f[0] == doJob ) {
          GM_setValue('selectMission', i);
          addToLog('process Icon', 'Switching job to ' + doJob + '.');
        }
        i++;
      }
    );
  }
  return;
}

function jobProgress(element) {
  if (GM_getValue('repeatJob', '') == 'checked' ) {
    DEBUG('Exiting jobProgress function; repeatJob is checked.');
    return;
  }

  var currentJob = missions[GM_getValue('selectMission', 1)][0];
  var jobno = missions[GM_getValue('selectMission', 1)][2];
  var tabno = missions[GM_getValue('selectMission', 1)][3];
  DEBUG('Calculating progress for ' + currentJob + '.');
  // Call for xpath differs based on quoting.
  // WARNING: This won't work if the job name has both double quotes (")
  //          and apostrophes ('). Back to the drawing board if that happens.
  var xQuote = (currentJob.indexOf('"') != -1) ?  '\'' : '"';
  var currentJobRow = xpath('//tr[contains(.,' + xQuote + currentJob + xQuote + ') and contains(.,\'Do Job\')]', element);
  if (!currentJobRow.snapshotLength) {
    addToLog('warning Icon', 'Unable to find Job Row for ' + currentJob + '.');
    var tierJobs = $x('//tr/td[@class=\'job_name\']', element);
    if (typeof(tierJobs[0]) == 'undefined') {
      addToLog('warning Icon', 'No jobs found in result. Checking page contents.');
      if (element.innerHTML.indexOf('Try Again')>0) {
        addToLog('warning Icon', "We are on the 'Try Again' error page.");
      }
    } else {
      addToLog('process Icon', tierJobs.length + ' jobs found in result page.');
      tierJobs.forEach(
        function(i) {
          var jobName = f.innerHTML.split('job_name">')[1].split('<br>')[0];
          DEBUG("Found job: " + jobName.trim());
        });
    }
    return;
  }

  // Calculate tier mastery.
  DEBUG("Checking mastery for each job.");
  var currentJobRowIndex = currentJobRow.snapshotLength - 1;
  var tierLevel = currentJobRow.snapshotItem(currentJobRowIndex).innerHTML.split('Level ')[1].match(/\d+/);
  var tierJobs = $x('//tr/td[@class=\'job_name\']', element);
  var tierPercent = 0;
  tierJobs.forEach(
    function(f) {
      if (f.innerHTML.indexOf('Mastered') != -1) {
        tierPercent += 100;
      } else {
        tierPercent += parseInt(f.innerHTML.split('Mastery ')[1].split('%')[0]);
      }
    }
  );
  if (tierJobs.length != 0) {
    tierPercent = Math.floor(tierPercent / tierJobs.length);
  }
  tierPercent = tierPercent + '';  //convert to string
  if (GM_getValue('tierCompleteStatus') != (tierLevel + '|' + String(tierPercent))) {
    GM_setValue('tierCompleteStatus', (tierLevel + '|' + String(tierPercent)));
    addToLog('info Icon', 'Job tier level ' + tierLevel + ' is ' + tierPercent + '% complete.');
  }

  // Calculate job mastery.
  DEBUG("Checking current job mastery.");
  var currentJobMastered = currentJobRow.snapshotItem(currentJobRowIndex).innerHTML.indexOf('Mastered');
  if (currentJobMastered > 0) {
    var jobs = getSavedList('jobsToDo');
    if (jobs.length == 0 || typeof(jobs.length) == 'undefined') {
      addToLog('info Icon', 'You have mastered the ' + currentJob + ' job.');
      DEBUG('Checking job tier mastery.');
      if (tierPercent == '100' ) {
        addToLog('info Icon', 'Current job tier is mastered. Will move to next tier.');
        var nextTierJobs = missions.searchArray(tabno + 1,3);
        if (typeof(nextTierJobs[0]) == 'undefined') {
          DEBUG('You have mastered the final tier!');
        } else {
          GM_setValue('selectMission', nextTierJobs[0]) + '';
          addToLog('info Icon', 'Current job switched to ' + missions[GM_getValue('selectMission', 1)][0] + '.');
        }
      } else {
          var findMastery = function(v,i,a) { return (a[i].innerHTML.indexOf('Mastery') > 0)? 1:0; };
          var nonMasteredJobs = tierJobs.filter(findMastery);
          var missionName = nonMasteredJobs[0].innerHTML.split('<br>')[0];
          GM_setValue('selectMission', missions.searchArray(missionName.trim(),0) + '');
          addToLog('info Icon', 'Current job switched to ' + missions[GM_getValue('selectMission', 1)][0] + '.');
      }
    } else {
      DEBUG("There are jobs in the to-do list.");
    }
  } else {
    DEBUG("Job is not mastered. Checking percent of mastery.");
    var jobPercentComplete = currentJobRow.snapshotItem(currentJobRowIndex).innerHTML.split('Mastery ')[1].split('%')[0];
    if (GM_getValue('jobCompleteStatus') != (currentJob + '|' + String(jobPercentComplete))) {
      GM_setValue('jobCompleteStatus', (currentJob + '|' + String(jobPercentComplete)));
      addToLog('info Icon', 'Job "' + currentJob + '" is ' + jobPercentComplete + '% complete.');
    }
  }
  return;
}

function jobLoot(element) {
  var lootbag = [];

  // See what loot was gained.
  var messages = $x('//td[@class=\'message_body\']', element);
  var numMessages = messages.length;
  for (i = 1; i < numMessages; i++) {
    messages[i].innerHTML.match(/You gained an* ([^.]+)\./);
    var loot = RegExp.$1;
    if (loot) {
      addToLog('lootbag Icon', '<span style="color:#FF6633;">'+' Found ' + loot + ' in the job.' + '</span>');
      lootbag.push(loot);
    }
  }

  var items = getSavedList('itemList');
  if (typeof(items[0]) == 'undefined' || items.length == 0) {
    DEBUG('No items in required item list.');
    return;
  }
  DEBUG('Found ' + lootbag.length + ' item(s) on this job.');

  var itemFound = false;
  var itemName;
  // NOTE: The single equal sign is intentional in this while() condition.
  while (itemName = lootbag.pop()) {
    DEBUG('Looking for ' + itemName + ' in needed items list.');
    DEBUG('We need ' + items.length + ' item(s).');
    for (j=0; j < items.length; j++) {
      if (itemName.indexOf(items[j]) != -1 ) {
        // we found some needed loot
        itemFound = true;
        addToLog('found Icon', itemName + ' is the item we were looking for!');
        removeSavedListItem('itemList', itemName);
        var jobList = getSavedList('jobsToDo');
        var doJob = jobList.pop();
        setSavedList('jobsToDo', jobList);

        for (k=0; k < missions.length; k++) {
          if (missions[k][0] == doJob) {
            addToLog('info Icon', 'Switching job to ' + doJob + '.');
            GM_setValue('selectMission', k);
            break;
          }
        }
      } else DEBUG(items[j] + ' not found in ' + itemName);
    }
  }
  if (!itemFound) {
    var jobResult;
    for (i=0; i < items.length; i++) {
      jobResult = requirementJob.searchArray(items[i],0);
      if (jobResult === false) {
        DEBUG('ERROR - ' + items[i] + ' not found in requirementJob array.');
      } else {
        if (missions[GM_getValue('selectMission', 1)][0] != requirementJob[jobResult][1]) {
          DEBUG('ERROR - ' + items[i] + ' cannot be found doing this job.');
        }
      }
      DEBUG(items[i] + ' not found.');
    }
  }
}

function debugDumpSettings() {
        //use the showIfUnchecked function to show 0 value as "un-checked"
        //use the showIfSelected function to show 0 value as "not selected" (for radio selections)
  DEBUG('  >  >  >  >  >  BEGIN SETTINGS DUMP  <  <  <  <  <   <br>' +
        'Script Version: <strong>' + SCRIPT.version + '</strong><br>' +
        'Player current level: <strong>' + level + '</strong><br>' +
        'Player points to next level: <strong>' + ptsToNextLevel + '</strong><br>' +
        'Player mafia size: <strong>' + mafia + '</strong><br>' +
        'Player current health: <strong>' + health + '</strong><br>' +
        'Player current Energy: <strong>' + energy + '</strong><br>' +
        'Player max energy: <strong>' + maxEnergy + '</strong><br>' +
        'Player max stamina: <strong>' + maxStamina + '</strong><br>' +
        'Player skill points: <strong>' + stats + '</strong><br>' +
        'Energy pack waiting: <strong>' + energyPack + '</strong><br>' +
        '--------------------General Tab---------------------<br>' +
        'Enable auto-refresh: <strong>' + showIfUnchecked(GM_getValue('autoClick'))+ '</strong><br>' +
        '&nbsp;&nbsp;-Refresh rate low: <strong>'+ GM_getValue('r1') + '</strong><br>' +
        '&nbsp;&nbsp;-Refresh rate high: <strong>' + GM_getValue('r2') + '</strong><br>' +
        'Enable auto-heal: <strong>' + showIfUnchecked(GM_getValue('autoHeal')) + '</strong><br>' +
        '&nbsp;&nbsp;-Minimum health: <strong>' + GM_getValue('healthLevel') + '</strong><br>' +
        '&nbsp;&nbsp;-Hide in hospital: <strong>' + showIfUnchecked(GM_getValue('hideInHospital')) + '</strong><br>' +
        'Enable auto-bank: <strong>' + showIfUnchecked(GM_getValue('autoBank')) + '</strong><br>' +
        '&nbsp;&nbsp;-Min bank amount: $<strong>' + GM_getValue('bankConfig') + '</strong><br>' +
        'Enable auto-pause: <strong>' + showIfUnchecked(GM_getValue('autoPause')) + '</strong><br>' +
        '&nbsp;&nbsp;-After level up: <strong>' + showIfSelected(GM_getValue('autoPauseAfter')) + '</strong><br>' +
        '&nbsp;&nbsp;-Before level up: <strong>' + showIfSelected(GM_getValue('autoPauseBefore')) + '</strong><br>' +
        '&nbsp;&nbsp;-Exp to pause at: <strong>'+ GM_getValue('autoPauseExp') + '</strong><br>' +
        'Left-align main frame: <strong>'+ showIfUnchecked(GM_getValue('leftAlign')) + '</strong><br>' +
        'Hide ads: <strong>'+ showIfUnchecked(GM_getValue('hideAds')) + '</strong><br>' +
        'Enable logging: <strong>' + showIfUnchecked(GM_getValue('priorLogSetting')) + '</strong><br>' +
        '&nbsp;&nbsp;-Logging length: <strong>' + GM_getValue('autoLogLength') + '</strong><br>' +
        'Log player updates: <strong>' + showIfUnchecked(GM_getValue('logPlayerUpdates')) + '</strong><br>' +
        'Enable auto-stat: <strong>' + showIfUnchecked(GM_getValue('autoStat')) + '</strong><br>' +
        '&nbsp;&nbsp;-Attack: <strong>' + showIfSelected(GM_getValue('autoStatAttack')) + '</strong><br>' +
        '&nbsp;&nbsp;-Defense: <strong>' + showIfSelected(GM_getValue('autoStatDefense')) + '</strong><br>' +
        '&nbsp;&nbsp;-Health: <strong>' + showIfSelected(GM_getValue('autoStatHealth')) + '</strong><br>' +
        '&nbsp;&nbsp;-Energy: <strong>' + showIfSelected(GM_getValue('autoStatEnergy')) + '</strong><br>' +
        '&nbsp;&nbsp;-Stamina: <strong>' + showIfSelected(GM_getValue('autoStatStamina')) + '</strong><br>' +
        'Delay rate low: <strong>'+ GM_getValue('d1') + '</strong><br>' +
        'Delay rate high: <strong>' + GM_getValue('d2') + '</strong><br>' +
        '--------------------Energy Tab---------------------<br>' +
        'Enable auto-mission: <strong>' + showIfUnchecked(GM_getValue('autoMission')) + '</strong><br>' +
        '&nbsp;&nbsp;-Job selected: <strong>' + missions[GM_getValue('selectMission')][0] + '</strong><br>' +
        '&nbsp;&nbsp;-Repeat Job: <strong>' + showIfUnchecked(GM_getValue('repeatJob')) + '</strong><br>' +
        'Wheelman savings: <strong>' + GM_getValue('selectEnergyBonus') + '%</strong><br>' +
        'Wait until energy full for jobs: <strong>' + showIfUnchecked(GM_getValue('waitForFull')) + '</strong><br>' +
        'Enable auto-energy pack: <strong>' + showIfUnchecked(GM_getValue('autoEnergyPack')) + '</strong><br>' +
        'Estimate Job Ratio: <strong>' + GM_getValue('estimateJobRatio') + '</strong><br>' +
        'Has helicopter: <strong>' + showIfUnchecked(GM_getValue('hasHelicopter')) + '</strong><br>' +
        '--------------------Fight/Rob Tab---------------------<br>' +
        'Enable auto-fight: <strong>' + showIfUnchecked(GM_getValue('autoFight')) + '</strong><br>' +
        'Enable auto-rob: <strong>' + showIfUnchecked(GM_getValue('autoRob')) + '</strong><br>' +
        '&nbsp;&nbsp;-Fight/Rob random mafia: <strong>' + showIfSelected(GM_getValue('fightRandom')) + '</strong><br>' +
        '&nbsp;&nbsp;-Max level: <strong>' + GM_getValue('fightLevel') + '</strong><br>' +
        '&nbsp;&nbsp;&nbsp;&nbsp;-Make max level relative: <strong>' + showIfUnchecked(GM_getValue('fightLevelRelative')) + '</strong><br>' +
        '&nbsp;&nbsp;-Max mafia: <strong>' + GM_getValue('fightmafiaSize') + '</strong><br>' +
        '&nbsp;&nbsp;&nbsp;&nbsp;-Make max mafia relative: <strong>' + showIfUnchecked(GM_getValue('fightMafiaRelative')) + '</strong><br>' +
        '&nbsp;&nbsp;-Min mafia: <strong>' + GM_getValue('fightmafiaMinSize') + '</strong><br>' +
        '&nbsp;&nbsp;&nbsp;&nbsp;-Make min mafia relative: <strong>' + showIfUnchecked(GM_getValue('fightMafiaMinRelative')) + '</strong><br>' +
        '&nbsp;&nbsp;-Use fight stealth: <strong>' + showIfUnchecked(GM_getValue('fightStealth')) + '</strong><br>' +
        '&nbsp;&nbsp;-Avoid Top Mafia bodyguards: <strong>' + showIfUnchecked(GM_getValue('fightAvoidBodyguards')) + '</strong><br>' +
        '&nbsp;&nbsp;-Fight/Rob from list: <strong>' + showIfSelected(GM_getValue('rFightList')) + '</strong><br>' +
        '&nbsp;&nbsp;&nbsp;&nbsp;-List: <strong>' + GM_getValue('fightList') + '</strong><br>' +
        'Avoid mafia families: <strong>' + showIfUnchecked(GM_getValue('clanMember')) + '</strong><br>' +
        '&nbsp;&nbsp;-Families list: <strong>' + GM_getValue('clanName') + '</strong><br>' +
        'Stamina to keep on hand: <strong>' + (100-(GM_getValue('selectStaminaKeep')*10)) + '% (keep above ' + staminaFloor + ')</strong><br>' +
        'Use stamina to level-up: <strong>' + showIfUnchecked(GM_getValue('allowStaminaToLevelUp')) + '</strong><br>' +
        '--------------------Hitlist Tab---------------------<br>' +
        'Enable auto-hitlist: <strong>' + showIfUnchecked(GM_getValue('autoHitlist')) + '</strong><br>' +
        '&nbsp;&nbsp;-Bounty amount: <strong>' + GM_getValue('bountyAmount') + '</strong><br>' +
        '&nbsp;&nbsp;&nbsp;&nbsp;-Hitlist: <strong>' + '' + '</strong><br>' +
        'Ride Hitlist: <strong>' + showIfUnchecked(GM_getValue('hideAttacks')) + '</strong><br>' +
        '--------------------Property Tab--------------------<br>' +
        'Enable auto-buy <strong>' + showIfUnchecked(GM_getValue('autoBuy')) + '</strong><br>' +
        '&nbsp;&nbsp;-Min cash: <strong>' + GM_getValue('buyMinAmount') + '</strong><br>' +
        'Enable auto-repair property <strong>' + showIfUnchecked(GM_getValue('autoRepair')) + '</strong><br>' +
        'Enable auto-protect property <strong>' + showIfUnchecked(GM_getValue('autoProtect')) + '</strong><br>' +
        '  >  >  >  >  >  END SETTINGS DUMP  <  <  <  <  <   ');
}

function parsePlayerUpdates (messagebox) {
  //var xw_time = messagebox.innerHTML.match(/xw_time=[^&]*/i);
  //var xw_exp_sig = messagebox.innerHTML.match(/xw_exp_sig=[^&]*/i);
  var inner = messagebox.innerHTML;
  if (inner.indexOf('attacked by') != -1) {
    // Attacked by some fool with a death wish.
    var elt = messagebox.getElementsByTagName('a')[0];
    var user;
    if (elt) {
      user = '<a style="color:#FFD927" href="' + elt.href + '">' +
             elt.innerHTML + '</a>';
    }
    if (inner.match(/You (?:<[^>]*>)?won.*You gained .*(\d+) experience points.*\$([0-9,]+)/)) {
      // The fight was won.
      var cost = RegExp.$2;
      var experience = RegExp.$1;
      var result = 'Attacked by ' + user +
                   '<span style="color:#52E259; font-weight:bold;">' +
                   ' WON $' + cost + '</span>' + ' and ' +
                   '<span style="color:#52E259; font-weight:bold;">' +
                   experience + ' experience.</span>';
      cost = parseInt(cost.replace(/,/g, ''));
      experience = parseInt(experience);

      if (GM_getValue('hideAttacks', '') == 'checked') {
        DEBUG('Riding Hitlist fight won.');
        GM_setValue('currentHitXp', parseInt((GM_getValue('currentHitXp', 0)) + experience));
        GM_setValue('currentHitDollars', parseInt((GM_getValue('currentHitDollars', 0)) + cost));
        DEBUG(result);
        if (experience == 0) {
          DEBUG('Zero experience detected; turning off auto-heal.');
          GM_setValue('autoHeal', 0);
        }
      } else {
        addToLog('updateGood Icon', result);
      }

      GM_setValue('fightWinCountInt', (GM_getValue('fightWinCountInt',1) + 1));
      GM_setValue('fightWinCountDisp', makeCommaValue(GM_getValue('fightWinCountInt',1)));
      GM_setValue('totalExpInt', (GM_getValue('totalExpInt', 1) + experience));
      GM_setValue('totalExpDisp', makeCommaValue(GM_getValue('totalExpInt', 1)));
      GM_setValue('totalWinDollarsInt', (GM_getValue('totalWinDollarsInt', 1) + cost));
      GM_setValue('totalWinDollarsDisp', '$' + makeCommaValue(GM_getValue('totalWinDollarsInt', 1)));
    } else if (inner.match(/You (?:<[^>]*>)?lost.*and losing .*\$([0-9,]+)/)) {
      // The fight was lost.
      var cost   = RegExp.$1;
      var result = 'Attacked by '+ user +
                   '<span style="color:#EC2D2D; font-weight:bold;">' +
                   ' LOST $' + cost + '.</span>';
      cost = parseInt(cost.replace(/,/g, ''));

      if (GM_getValue('hideAttacks', '') == 'checked') {
        DEBUG('Ride Hitlist fight lost.');
        GM_setValue('currentHitDollars', parseInt((GM_getValue('currentHitDollars', 0)) - cost));
        DEBUG(result);
      } else {
        addToLog('updateBad Icon', result);
      }

      GM_setValue('fightLossCountInt', (GM_getValue('fightLossCountInt',1) + 1));
      GM_setValue('fightLossCountDisp', makeCommaValue(GM_getValue('fightLossCountInt',1)));
      GM_setValue('totalLossDollarsInt', (GM_getValue('totalLossDollarsInt', 1) + cost));
      GM_setValue('totalLossDollarsDisp', '$' + makeCommaValue(GM_getValue('totalLossDollarsInt', 1)));
    } else {
      addToLog('warning Icon','BUG DETECTED: Unable to read update win/loss.');
    }

  } else if (inner.indexOf('You were snuffed') != -1) {
    // Death. Ouch.
    addToLog('updateBad Icon', 'You <span style="color:#EC2D2D;">' + 'DIED' + '</span>.');

  } else if (inner.indexOf('You were knocked out') != -1) {
    // Hitlist ride has ended.
    var elts = messagebox.getElementsByTagName('a');
    var hitman, user;
    if (elts[0]) {
      hitman = '<a style="color:#FFD927" href="' + elts[0].href + '">' +
               elts[0].innerHTML + '</a>';
    }
    if (elts[1]) {
      user = '<a style="color:#EC2D2D" href="' + elts[1].href + '">' +
             elts[1].innerHTML + '</a>';
    }
    var bounty = parseInt(inner.split(' who claimed the $')[1].replace(/,/g, ''));
    var result = 'Whacked by '+ hitman + ' who claimed the $' +
                 makeCommaValue(parseInt(bounty)) + ' bounty set by ' +
                 user + '.';

    if (GM_getValue('hideAttacks', '') == 'checked') {
      DEBUG('Whacked riding hitlist.');
      GM_setValue('currentHitXp', parseInt((GM_getValue('currentHitXp', 0) - 6)));
      GM_setValue('totalHits', parseInt(GM_getValue('totalHits', 0)) + 1);
      GM_setValue('totalXp', parseInt(GM_getValue('totalXp', 0)) + parseInt(GM_getValue('currentHitXp',0)));
      GM_setValue('lastHitXp', parseInt(GM_getValue('currentHitXp',0)));
      GM_setValue('totalHitDollars', parseInt((GM_getValue('currentHitDollars', 0)) + parseInt(GM_getValue('totalHitDollars', 0))));
      if (GM_getValue('currentHitXp', 0) < 0) {
        var currentHitXp = '<span style="color:#EC2D2D; font-weight:bold;">LOST ' + GM_getValue('currentHitXp', 0) + '</span>';
      } else {
        var currentHitXp = '<span style="color:#52E259; font-weight:bold;">GAINED ' + GM_getValue('currentHitXp', 0) + '</span>';
      }
      if (GM_getValue('currentHitDollars',0) < 0) {
        var currentHitDollars = '<span style="color:#EC2D2D; font-weight:bold;">' +
                                ' LOST $' + makeCommaValue(parseInt(GM_getValue('currentHitDollars',0))) + '</span>';
  addToLog('updateBad Icon', currentHitXp + ' experience and ' + currentHitDollars + ' on the hitlist.');
      } else {
        var currentHitDollars = '<span style="color:#52E259; font-weight:bold;">' +
                                ' WON $' + makeCommaValue(parseInt(GM_getValue('currentHitDollars',0))) + '</span>';
        addToLog('updateGood Icon', currentHitXp + ' experience and ' + currentHitDollars + ' on the hitlist.');
      }

      DEBUG('Hitlist total values set; now clearing current values.');
      GM_setValue('currentHitXp', 0);
      GM_setValue('currentHitDollars',0);
      DEBUG('Ensure that autoHeal is enabled.');
      GM_setValue('autoHeal', 'checked');

    }
    addToLog('updateBad Icon', result);

  } else if (inner.indexOf('You were punched') != -1) {
    // Punched by some wuss.
    var elt = messagebox.getElementsByTagName('a')[0];
    var user;
    if (elt) {
      user = '<a style="color:#EC2D2D" href="' + elt.href + '">' +
             elt.innerHTML + '</a>';
    }
    var result = 'You were punched in the face by ' + user + '.';
    addToLog('updateBad Icon', result);

  } else if (inner.indexOf('You fought as') != -1) {
    // Helped a fellow mafia member in a fight.
    var elts = messagebox.getElementsByTagName('a');
    var capo, user;
    if (elts[0]) {
      capo = '<a style="color:#FFD927" href="' + elts[0].href + '">' +
             elts[0].innerHTML + '</a>';
    }
    if (elts[1]) {
      user = '<a style="color:#EC2D2D" href="' + elts[1].href + '">' +
             elts[1].innerHTML + '</a>';
    }
    var cost = parseInt(inner.split('$')[1].replace(/,/g, ''));
    var result = 'You fought as ' + capo + "'s Capo and defeated " +
                 user + ', receiving' +
                 '<span style="color:#52E259; font-weight:bold;">' +
                 ' $' + makeCommaValue(cost) + '</span> for your efforts.';
    addToLog('updateGood Icon', result);

  } else if (inner.indexOf('needs your help on a job') != -1) {
    // Help requested by a fellow mafia member.
    inner.split(/target_id=(\d+)/);
    var targetid = RegExp.$1;
    if (targetid) {
      var link = 'http://apps.facebook.com/' + SCRIPT.name +
                 SCRIPT.controller + 'job' +
                 SCRIPT.action + 'give_help' +
                 '&target_id=' + RegExp.$1 +
                 '&skip_interstitial=1';
      takeAction(link, 'help');
    } else {
      addToLog('warning Icon','BUG DETECTED: Unable to read help target.');
    }

  } else if (inner.indexOf('claimed your $') != -1) {
    // Bounty claimed. Whoever was hitlisted is sleeping with the fishes.
    var elts = messagebox.getElementsByTagName('a');
    var hitman, user;
    if (elts[0]) {
      hitman = '<a style="color:#FFD927" href="' + elts[0].href + '">' +
               elts[0].innerHTML + '</a>';
    }
    if (elts[1]) {
      user = '<a style="color:#EC2D2D" href="' + elts[1].href + '">' +
             elts[1].innerHTML + '</a>';
    }
    var result = hitman + ' claimed your ' + inner.match(/\$[\d\,]+/)[0] +
                 ' bounty on ' + user + '.';
    addToLog('updateGood Icon', result);

  } else if (inner.indexOf('tried to rob you!') != -1) {
    // Robbery.
    var elts = messagebox.getElementsByTagName('a');
    var thief;
    if (elts[0]) {
      thief = '<a style="color:#EC2D2D" href="' + elts[0].href + '">' +
              elts[0].innerHTML + '</a>';
    }
    inner.match(/dealing (?:<[^>]*>)([0-9,]+)/);
    var damage = RegExp.$1;
    damage = damage.replace(/,/g, '');
    var result = thief + ' tried to rob you!<br>' +
                 'You taught \'em a lesson and spanked \'em for ' +
                 damage + ' damage.';
    addToLog('updateGood Icon', result);

  } else {
    // Just copy the text straight into the log.
    //FIXME: This relies on specific content a bit too much.
    //       Maybe find the element and use its innerHTML
    result = inner.split('update_txt">')[1].split('</div>')[0];
    addToLog('updateGood Icon', result);
  }
}

function profileFix() {
  var itemLists = xpath('//ul[@class=\'nice_list items_list clearfix\']');
  var itemCount = [];
  for (whichblock = 0; whichblock < 3; whichblock++) {
    itemCount[whichblock] = 0;
    var i = 0;
    var nexti = 0;
    while ((i != -1) && (nexti < itemLists.snapshotItem(whichblock).innerHTML.length)) {
      i = itemLists.snapshotItem(whichblock).innerHTML.indexOf('X&nbsp;',nexti);
      if (i != -1) {
        var nextwhitespace = itemLists.snapshotItem(whichblock).innerHTML.indexOf('</div>',i);
        itemCount[whichblock] += parseInt(itemLists.snapshotItem(whichblock).innerHTML.substring(i+7,nextwhitespace));
        nexti = i + 1;
      }
    }
  }

  var findWeapons = xpath('//div[@class=\'title\']');
  var greenText = 'color:#52E259;';
  var redText = 'color:#EC2D2D;';
  if (findWeapons.snapshotLength > 5) {
    if (findWeapons.snapshotItem(3).innerHTML.ltrim().rtrim() == 'Weapons') {
      if (mafia <= itemCount[0])
        j = makeElement('span', findWeapons.snapshotItem(3), {'style':greenText});
      else
        j = makeElement('span', findWeapons.snapshotItem(3), {'style':redText});
      j.appendChild(document.createTextNode('(' + itemCount[0] + ')'));
    }
    if (findWeapons.snapshotItem(4).innerHTML.ltrim().rtrim() == 'Defense') {
      if (mafia <= itemCount[1])
        j = makeElement('span', findWeapons.snapshotItem(4), {'style':greenText});
      else
        j = makeElement('span', findWeapons.snapshotItem(4), {'style':redText});
      j.appendChild(document.createTextNode(' (' + itemCount[1] + ')'));
    }
    if (findWeapons.snapshotItem(5).innerHTML.ltrim().rtrim() == 'Vehicles') {
      if (mafia <= itemCount[2])
        j = makeElement('span', findWeapons.snapshotItem(5), {'style':greenText});
      else
        j = makeElement('span', findWeapons.snapshotItem(5), {'style':redText});
      j.appendChild(document.createTextNode('(' + itemCount[2] + ')'));
    }
  }
}

function propertyBuy() {
  if (document.getElementById(SCRIPT.appID+'_property') == -1) {
    window.setTimeout(propertyBuy,1000);
  }
  var buyType = GM_getValue('buyType', 0);
  var buyName = GM_getValue('buyName', '');
  var buyCost = GM_getValue('buyCost', 0);
  var buySelection = GM_getValue('selectProperties', '');
  var buyRequired  = GM_getValue('buyRequired', '');
  var buySuccess = false;
  DEBUG('Auto-buy: name=' + buyName + ', id=' + buyType + ', cost=' + buyCost + ', req=' + buyRequired + ', mafia=' + mafia);
  if (buyCost > 0 && buyCost < (cash - GM_getValue('buyMinAmount', 0)) && buyType > 0 && (buyRequired || buySelection.indexOf(buyName) > -1)) {
    var buyamount = xpath('//form[@id=\''+SCRIPT.appID+'_propBuy_' + buyType + '\']/table/tbody/tr/td/select[@name=\'amount\']');
    if (buyamount.snapshotItem(0) == null ) {
      window.setTimeout(propertyBuy,1000);
    } else {
      if (buyamount.snapshotLength > 0) {
        var buyamountSelects = buyamount.snapshotItem(0);
        if (buyamountSelects.length) {
          buyamountSelects[buyamountSelects.length - 1].selected = true;
          var buyform = xpath('//form[@id=\''+SCRIPT.appID+'_propBuy_' + buyType + '\']/table/tbody/tr/td[2]/span/input');
          if (buyform.snapshotLength) {
            buySuccess = true;
            buyform.snapshotItem(0).click();
            propertyCheckBuy();
          }
        }
      }
    }
  } else {
    propertyGet();
  }
  if (!buySuccess) {
    Autoplay.delay = delay;
    Autoplay.start();
  }
}

function propertyCheckBuy() {
  var messageCheck = xpath('//div[@class=\'message_float\']');
  if (messageCheck.snapshotItem(0) == null) {
    window.setTimeout(propertyCheckBuy,1000);
  }
  Autoplay.fx = goPropertyTab;
  Autoplay.delay = delay;
  Autoplay.start();
}

function propertyGet() {
  if (document.getElementById(SCRIPT.appID+'_property') == -1) {
      window.setTimeout(propertyGet,1000);
  }

  // check for messages
  var messageCheck = xpath('//div[@class=\'message_float\']');

  if (messageCheck.snapshotLength) {
    messageCheck = messageCheck.snapshotItem(0).innerHTML.replace(/<[a-zA-Z\/][^>]*>/g, ''); // strip html tags
    if (messageCheck.match(/You just bought (.*) for (\$[\d\,]+)/)) {
      addToLog('cash Icon', '<strong>Bought</strong> ' +
               '<span style="color:#52E259; font-weight:bold;">' +
               RegExp.$1 + '</span>' + ' for ' +
               '<span style="color:#52E259; font-weight:bold;">' +
               RegExp.$2 + '</span>.');
    } else {
      addToLog('warning Icon', 'Auto-buy error: ' + messageCheck);
    }

  } else {
    var messageCheck = xpath('//td[@class=\'message_body\']');
    if (messageCheck.snapshotLength) {
      messageCheck = messageCheck.snapshotItem(0).innerHTML.replace(/<[a-zA-Z\/][^>]*>/g, ''); // strip html tags
      if (messageCheck.match(/You successfully sold (.*) for (\$[\d\,]+)/)) {
        addToLog('cash Icon', '<strong>Sold</strong> ' +
                 '<span style="color:#EC2D2D; font-weight:bold;">' +
                 RegExp.$1 + '</span>' + ' for ' +
                 '<span style="color:#52E259; font-weight:bold;">' +
                 RegExp.$2 + '</span>.');
      } else {
        addToLog('info Icon', messageCheck);
      }
    }
  }

  var allPropertyRowsPath = '//td[@id=\''+SCRIPT.appID+'_content_row\']/table[@class=\'main_table\']/tbody/tr';
  var allPropertyRows = xpath(allPropertyRowsPath);

  // get number of payments per day
  var tempObj = xpath('//td[@id=\''+SCRIPT.appID+'_content_row\']/div[2]');
  if (tempObj.snapshotLength && tempObj.snapshotItem(0).innerHTML.match(/every (.+) minutes/)) {
    var payments = 1440 / parseInt(RegExp.$1);
  } else {
    var payments = 24;
  }

  if (allPropertyRows.snapshotLength > 0) {
    var allProperties = new Array();
    var bestProperty = { id:false, roi:0, row:0 };
    var selectProperties = GM_getValue('selectProperties', '');

    for (var currentRow = 0; currentRow < allPropertyRows.snapshotLength; currentRow++) {
      var currentRowHtml = allPropertyRows.snapshotItem(currentRow).innerHTML;

      if (/prop_[\w\d]+\.jpg/.test(currentRowHtml)) {
        var currentProperty = { id:0, roi:0, cost:0, name:'', row:0, path:'', income:0, mobsize:0, amount:0, owned:0, requiredId:0, requiredCost:0, requiredName:'' }
        var currentRowXpath = allPropertyRowsPath + "[" + (currentRow+1) + "]/";

        // get id
        var tempObj = xpath(currentRowXpath + 'td[3]/table/tbody/tr/td[2]/form/table/tbody/tr/td/input[@name=\'property\']');
        if (tempObj.snapshotLength) {
          currentProperty.id = tempObj.snapshotItem(0).value;
        }

        // get required mafia size
        tempObj = xpath(currentRowXpath + "td[3]/table/tbody/tr[1]/td[1]");
        if (tempObj.snapshotLength) {
          currentProperty.mobsize = tempObj.snapshotItem(0).innerHTML.match(/<strong>(\d+)<\/strong>/) ? parseInt(RegExp.$1) : 0;
        }

        // get max buy amount and select
        tempObj = xpath('//form[@id=\''+SCRIPT.appID+'_propBuy_' + currentProperty.id + '\']/table/tbody/tr/td/select[@name=\'amount\']');
        if (tempObj.snapshotLength) {
          tempObj = tempObj.snapshotItem(0);
          if (tempObj.length) {
            currentProperty.amount = tempObj.length;
            tempObj[currentProperty.amount - 1].selected = true;
          }
        }

        // get name & income
        tempObj = xpath(currentRowXpath + "td[2]/strong | " + currentRowXpath + "td[2]/div/strong");
        if (tempObj.snapshotLength) {
          currentProperty.name = tempObj.snapshotItem(0).innerHTML;
          currentProperty.income = parseInt(tempObj.snapshotItem(1).innerHTML.replace(/\,/g,'').replace(/\$/g,''));
        }

        tempObj = xpath(currentRowXpath + "/td[3]/table/tbody/tr[2]/td | " + currentRowXpath + "td[2]/div/strong");

        // get cost
        tempObj = xpath(currentRowXpath + "td[3]/table/tbody/tr[1]/td");
        if (tempObj.snapshotLength) {
          tempObj = tempObj.snapshotItem(0).innerHTML;
          if (tempObj) {
            // cost of required undeveloped space
            if (tempObj.match(/Built On: ([\w\s]+)/)) {
              for (var j=0; j < allProperties.length; j++) {
                if (allProperties[j].name == RegExp.$1) {
                  currentProperty.requiredCost = allProperties[j].cost;
                  if (allProperties[j].owned < currentProperty.amount) {
                    currentProperty.requiredId   = allProperties[j].id;
                    currentProperty.requiredName = allProperties[j].name;
                  }
                  break;
                }
              }
            }
            // cost of property
            if (tempObj.match(/\$([\d,]+)/)) {
              currentProperty.cost = parseInt(RegExp.$1.replace(/\,/g,''));
            }
          }
        }

        // get number of owned
        tempObj = xpath(currentRowXpath + "td[3]/table/tbody/tr[2]/td");
        if (tempObj.snapshotLength && tempObj.snapshotItem(0).innerHTML.match(/([\d]+)/)) {
          currentProperty.owned = RegExp.$1;
        } else {
          tempObj = xpath(currentRowXpath + "td[2]/div/strong[2]");
          if (tempObj.snapshotLength && tempObj.snapshotItem(0).innerHTML.match(/([\d]+)/)) {
            currentProperty.owned = RegExp.$1;
          }
        }

        // calculate roi and check if its the highest
        if (currentProperty.income > 0 && currentProperty.cost > 0) {
          currentProperty.roi = currentProperty.income / (currentProperty.cost + currentProperty.requiredCost);
          if (selectProperties.indexOf(currentProperty.name) != -1 && bestProperty.roi < currentProperty.roi && mafia >= currentProperty.mobsize) {
            bestProperty = currentProperty;
            bestProperty.row  = currentRow;
            tempObj = xpath(currentRowXpath + "td[3]/table/tbody/tr[1]/td/strong");
            bestProperty.path = tempObj.snapshotItem(0);
          }
        }

        // display roi & total income on page
        if (currentProperty.roi > 0) {
          var tempItem = xpath(currentRowXpath + 'td[2]/strong').snapshotLength == 1 ? 0 : 1;
          var roiText = xpath(currentRowXpath + 'td[2]/div');
          roiText = makeElement('div', roiText.snapshotItem(tempItem), {'style':'margin:10px 0 10px 0; font-size:13px'});
          roiText.appendChild(document.createTextNode('Total Income: $' + makeCommaValue(currentProperty.owned * currentProperty.income)));
          roiText.appendChild(document.createElement("br"));
          roiText.appendChild(document.createTextNode('ROI: '));
          makeElement('strong', roiText, { 'style':'color:#FFD927'}).appendChild(document.createTextNode(''+Math.round(currentProperty.roi*100000000)/100000));
          var roiTime = (1/currentProperty.roi) / payments; // days
          if (roiTime > 3652.5) { // display years
            roiTime /= 365.25;
            var roiTimeText = ' years)';
          } else if (roiTime > 365.25) { // display months
            roiTime /= 30.4375;
            var roiTimeText = ' months)';
          } else {
            var roiTimeText = ' days)';
          }
          roiText.appendChild(document.createTextNode(' (' + (Math.round(roiTime * 100) / 100) + roiTimeText));
        }

        allProperties.push(currentProperty);
      }
    }

    // display next property
    if (GM_getValue('autoBuy', 0)) {
      if (bestProperty.requiredId > 0) {
        makeElement('div', xpath('//td[@id=\''+SCRIPT.appID+'_content_row\']/div[@class=\'text\']').snapshotItem(0), {'style':'margin-top:12px'}).appendChild(document.createTextNode('Next auto-buy property: ' + bestProperty.amount + 'x ' + bestProperty.requiredName + ' ($' + makeCommaValue(bestProperty.requiredCost * bestProperty.amount) + ') to build ' + bestProperty.name));
      } else {
        makeElement('div', xpath('//td[@id=\''+SCRIPT.appID+'_content_row\']/div[@class=\'text\']').snapshotItem(0), {'style':'margin-top:12px'}).appendChild(document.createTextNode('Next auto-buy property: ' + bestProperty.amount + 'x ' + bestProperty.name + ' ($' + makeCommaValue(bestProperty.cost * bestProperty.amount) + ')'));
      }
    }

    // highlight best property
    if (bestProperty.row > 0) {
      allPropertyRows.snapshotItem(bestProperty.row).style.backgroundColor="#020";
      best = makeElement('div', bestProperty.path, {'style':'color:#52E259; font-size: 11px; margin-top:10px'});
      makeElement('img', best, {'src':stripURI(goodIcon), 'width':'12', 'height':'12', 'style':'vertical-align:middle'});
      best.appendChild(document.createTextNode(' BEST'));
    }

    if (bestProperty.requiredId > 0 && (GM_getValue('buyType', 0) != bestProperty.requiredId || GM_getValue('buyCost', 0) != bestProperty.requiredCost * bestProperty.amount)) {
      GM_setValue('buyName', bestProperty.requiredName);
      GM_setValue('buyType', bestProperty.requiredId);
      GM_setValue('buyCost', '' + bestProperty.requiredCost * bestProperty.amount);
      GM_setValue('buyRequired', 1);
      addToLog('process Icon', 'Next auto-buy property: ' + bestProperty.amount + 'x <span style="color:#52E259; font-weight:bold;">' + bestProperty.requiredName + '</span> (<span style="color:#FFD927">$' + makeCommaValue(bestProperty.requiredCost * bestProperty.amount) + '</span>) to build ' + bestProperty.name);
    } else if (GM_getValue('buyType', 0) != bestProperty.id || GM_getValue('buyCost', 0) != bestProperty.cost * bestProperty.amount) {
      GM_setValue('buyName', bestProperty.name);
      GM_setValue('buyType', bestProperty.id);
      GM_setValue('buyCost', '' + bestProperty.cost * bestProperty.amount);
      GM_setValue('buyRequired', 0);
      addToLog('process Icon', 'Next auto-buy property: ' + bestProperty.amount + 'x <span style="color:#52E259; font-weight:bold;">' + bestProperty.name + '</span> (<span style="color:#FFD927">$' + makeCommaValue(bestProperty.cost * bestProperty.amount) + '</span>)');
    }
    
    DEBUG('Next auto-buy: name=' + GM_getValue('buyName', '') + ', id=' + GM_getValue('buyType', '') + ', cost=' + GM_getValue('buyCost', '') + ', req=' + GM_getValue('buyRequired', '') + ', reqMafia=' + bestProperty.mobsize + ', mafia=' + mafia);
  }
}

function loadHome() {
  document.location = 'http://apps.facebook.com/inthemafia/index.php';
}

function loadBank() {
  document.location = 'http://apps.facebook.com/' + SCRIPT.name +
                      SCRIPT.controller + 'bank' +
                      SCRIPT.action + 'view';
}

function loadFightTab() {
  document.location = 'http://apps.facebook.com/' + SCRIPT.name +
                      SCRIPT.controller + 'fight' +
                      SCRIPT.action + 'view';
}

function loadPropertyTab() {
    document.location = 'http://apps.facebook.com/' + SCRIPT.name +
                        SCRIPT.controller + 'property' +
                        SCRIPT.action + 'view';
}

function clickElement(elt) {
  if (!elt) {
    DEBUG('BUG DETECTED: Null element passed to clickElement().');
    return;
  }

  // Simulate a mouse click on the element.
  var evt = document.createEvent('MouseEvents');
  evt.initMouseEvent("click", true, true, window,
                     0, 0, 0, 0, 0, false, false, false, false, 0, null);
  elt.dispatchEvent(evt);
}

function goLinkElement(elt) {
  if (!elt) {
    DEBUG('BUG DETECTED: Null element passed to goLinkElement().');
    return;
  }

  if (!useClickSimulation) {
    document.location = elt.href;
  } else {
    clickElement(elt);
    DEBUG('Clicked element.');
  }
}

function goHome() {
  if (!useClickSimulation) {
    loadHome();
    return;
  }

  var elt = xpath('//div[@class=\'nav_link home_link\']/a').snapshotItem(0);
  if (!elt) {
    addToLog('BUG DETECTED: Can\'t find home link to click.');
    loadHome();
    return;
  }
  clickElement(elt);
  DEBUG('Clicked to go home.');
}

function goBank() {
  if (!useClickSimulation) {
    loadBank();
    return;
  }

  var elt = xpath('//a[@class=\'bank_deposit\']').snapshotItem(0);
  if (!elt) {
    addToLog('BUG DETECTED: Can\'t find bank link to click.');
    loadBank();
    return;
  }
  clickElement(elt);
  DEBUG('Clicked to go to bank.');
}

function goFightTab() {
  if (!useClickSimulation) {
    loadFightTab();
    return;
  }

  var elt = xpath('//div[@class=\'nav_link fight_link\']/a').snapshotItem(0);
  if (!elt) {
    addToLog('BUG DETECTED: Can\'t find fight tab link to click.');
    loadFightTab();
    return;
  }
  clickElement(elt);
  DEBUG('Clicked to go to fight tab.');
}

function goPropertyTab() {
  if (!useClickSimulation) {
    loadPropertyTab();
    return;
  }

  var elt = xpath('//div[@class=\'nav_link properties_link\']/a').snapshotItem(0);
  if (!elt) {
    addToLog('BUG DETECTED: Can\'t find properties tab link to click.');
    loadPropertyTab();
    return;
  }
  clickElement(elt);
  DEBUG('Clicked to go to properties tab.');
}

function logResponse (responseDetails, action) {
  //  DEBUG('logResponse: status='+ responseDetails.status);
  //  DEBUG('logResponse: statusText='+ responseDetails.statusText);
  //  DEBUG('logResponse: responseHeaders='+ responseDetails.responseHeaders);
  //  DEBUG('logResponse: responseText='+ responseDetails.responseText);

  // Check for error pages.
  if (responseDetails.responseText.indexOf('Error while loading page') != -1) {
    DEBUG('Error loading response page.');
    return;
  }
  if (responseDetails.responseText.indexOf('request was not processed') != -1) {
    DEBUG('Request was not processed.');
    return;
  }
  if (responseDetails.responseText.indexOf('Sign up and use Mafia Wars') != -1) {
    addToLog('warning Icon', '<span style="color:#EC2D2D">WARNING:</span> Reached the Mafia Wars login page.');
    addToLog('warning Icon', '<span style="color:#EC2D2D">Please adjust your browser\'s settings to allow third-party cookies.</span>');
    addToLog('warning Icon', '<span style="color:#EC2D2D">Or is this Facebook user logged in on another computer?</span>');
    return;
  }

  var doc = document.createElement('div');
  doc.innerHTML = responseDetails.responseText;
  var results = xpath('//table[@class=\'messages\']', doc);
  var messagebox = results.snapshotItem(0);
  if (!messagebox && action != 'propDmgChk') {
    DEBUG('logResponse: responseText='+ responseDetails.responseText);
    DEBUG('Unexpected response page: no message box found!');
    return;
  }
  var inner = messagebox? messagebox.innerHTML : '';
  var xw_time = doc.innerHTML.match(/xw_time=[^&]*/i);
  var xw_exp_sig = doc.innerHTML.match(/xw_exp_sig=[^&]*/i);

  switch (action) {
    case 'fight':   //fight
      var messages = $x('//td[@class=\'message_body\']', messagebox);
      var elt = messages[0]? messages[0].firstChild : undefined;
      if (elt && elt.nodeValue.indexOf(' fought against ') != -1) {
        // First, look for any new opponents in the displayed list.
        // NOTE: This is at the top because putting it lower would risk
        //       it not getting called at all if an error occurs. This
        //       can lead to fighting the same opponents over and over.
        if (GM_getValue('fightRandom', '') == 'checked') {
          findNewFightOpponent(doc);
        }

        // If fighting from the user-specified list, cycle it.
        if (GM_getValue('rFightList', '') == 'checked') {
          CycleFightList();
        }

        // Determine whether the opponent is alive and may see future attacks.
        if (inner.indexOf('Attack Again') != -1) {
          setFightOpponentActive();
        } else {
          setFightOpponentInactive();
        }

        // Get the opponent.
        elt = elt.nextSibling;
        var user;
        if (elt) {
          user = '<a style="color:#FFD927" href="' + elt.href + '">' +
                 elt.innerHTML + '</a>';
          if (messages[1] && messages[1].innerHTML.match(/<\/a>('s Mafia of [\d]+)/)) {
           user += RegExp.$1;
          }
        } else {
          addToLog('warning Icon','BUG DETECTED: Unable to read user name.');
        }

        if (inner.match(/You (?:<[^>]*>)?WON.*You gained .*\$([0-9,]+).*(\d+) experience points/)) {
          // The fight was won.
          var cost = RegExp.$1;
          var experience = RegExp.$2;
          var result = 'Fought ' + user +
                       ' <span style="color:#52E259; font-weight:bold;">' +
                       'WON $' + cost + '</span>' + ' and ' +
                       '<span style="color:#52E259; font-weight:bold;">' +
                       experience + ' experience</span>.';

          // Check for a lucky win.
          if (inner.indexOf('against all odds') != -1) {
            result += ' <span style="color:#EC2D2D;">(against all odds)</span>';
            setFightOpponentAvoid();
          }

          addToLog('good Icon', result);

          GM_setValue('fightWinCountInt', (GM_getValue('fightWinCountInt', 0) + 1));
          GM_setValue('totalExpInt', (GM_getValue('totalExpInt', 0) + parseInt(experience)));
          GM_setValue('totalWinDollarsInt', (GM_getValue('totalWinDollarsInt', 0) + parseInt(cost.replace(/,/g, ''))));
        } else if (inner.match(/You (?:<[^>]*>)?LOST.*along with .*\$([0-9,]+)/)) {
          // The fight was lost.
          var cost   = RegExp.$1;
          var result = 'Fought ' + user +
                       ' <span style="color:#EC2D2D; font-weight:bold;">' +
                       'LOST $' + cost + '.</span>';

          GM_setValue('fightLossCountInt', (GM_getValue('fightLossCountInt', 0) + 1));
          GM_setValue('totalLossDollarsInt', (GM_getValue('totalLossDollarsInt', 0) + parseInt(cost.replace(/,/g, ''))));

          // Check for a critical hit.
          if (inner.indexOf('critical hit') != -1) {
            if (inner.indexOf('Top Mafia Bodyguard') != -1) {
              result += ' <span style="color:#EC2D2D;">(bodyguard critical hit)</span>';
              if (GM_getValue('fightRandom', '') == 'checked' &&
                  GM_getValue('fightAvoidBodyguards', '') == 'checked') {
                setFightOpponentAvoid();
              }
            } else {
              result += ' <span style="color:#EC2D2D;">(critical hit)</span>';
            }
          } else {
            // Don't fight this opponent again.
            result += ' Too strong! Avoiding.';
            setFightOpponentAvoid();
          }

          addToLog('bad Icon', result);
        } else {
          addToLog('warning Icon','BUG DETECTED: Unable to read win or loss.');
        }

        // Check for any fatalities.
        if (inner.indexOf('took out your opponent') != -1) {
          addToLog('info Icon', killedMobsterIcon + ' You <span style="color:#EC2D2D;">' + 'KILLED' + '</span> ' + user + '.');
        }
        if (inner.indexOf('You were snuffed') != -1) {
          addToLog('bad Icon', 'You <span style="color:#EC2D2D;">' + 'DIED' + '</span> in the fight.');
        }

        // Look for any loot.
        if (inner.match('found an? (.*) while fighting')) {
          addToLog('lootbag Icon', '<span style="color:#FF6633;">'+' Found '+
                   RegExp.$1 + ' in the fight.</span>');
        }

        // Update fight log tracking statistics.
        updateLogStats();
      } else if (inner.indexOf('too weak to fight') != -1) {
        addToLog('info Icon', '<span style="color:#FF9999;">' + 'Too weak to fight.'+ '</span>');
      } else if (inner.indexOf('You cannot fight') != -1) {
        setFightOpponentAvoid();
      } else {
        DEBUG('Unrecognized fight response.');
      }
      break;
    case 'heal':    //heal
      if (inner.indexOf('doctor healed') != -1) {
        var addHealth = inner.split('doctor healed <strong>')[1].split('health')[0];
        var cost = 0;
        if (inner.indexOf('$') != -1) {
          cost = inner.split('$')[1];
        }
        cost = cost.replace(/,/g, '');
        cost   = parseInt(cost  );
        addToLog('health Icon', '<span style="color:#FF9999;">' + ' Health +'+ addHealth + ' for $' + makeCommaValue(cost)+ '.</span>');
      } else if (inner.indexOf('You cannot heal so fast') != -1) {
        addToLog('warning Icon', '<span style="color:#FF9999;">' + 'Attempted to heal too quickly.' + '</span>');
      }
      break;
    case 'job':
      xpGainElt = xpath('//dd[@class=\'message_experience\']', messagebox).snapshotItem(0);
      if (xpGainElt) {
        // Job completed successfully.
        var cash_gained = $x('//dd[@class=\'message_cash\']', messagebox);
        cash_gained = cash_gained[0] != undefined ? ' and <font style="color:#52E259; font-weight:bold;">' + cash_gained[0].innerHTML + '</font>' : '';
        addToLog('process Icon', 'You performed ' + '<font style="color:#52E259; font-weight:bold;">' + missions[GM_getValue('selectMission')][0] + '</font> earning <font style="color:#52E259; font-weight:bold;">' + xpGainElt.innerHTML + '</font>' + cash_gained + '.');
        jobProgress(doc);
        if (inner.indexOf('You gained ') != -1) {
          jobLoot(doc);
        }
        // Add message if job tier prize found.
        if (inner.match(/.*(An* .+ was added to your inventory[^.]*.)/)) {
          addToLog('lootbag Icon', RegExp.$1);
        }
      } else if (inner.indexOf('You don\'t have the necessary items to perform this job') != -1) {
        addToLog('info Icon', 'You don\'t have the items necessary to do ' + missions[GM_getValue('selectMission', 1)][0] + '.');
        jobReqs(doc);
      } else if (inner.indexOf('You are not high enough level to do this job') != -1) {
        addToLog('warning Icon', 'You are not high enough level to do ' + missions[GM_getValue('selectMission', 1)][0] + '.');
        addToLog('warning Icon', 'Job processing will stop');
        GM_setValue('autoMission', 0);
      }
      Autoplay.delay = delay;
      Autoplay.start();
      break;
    case 'rob':
      // NOTE: This is at the top because putting it lower would risk
      //       it not getting called at all if an error occurs. This
      //       can lead to robbing the same opponent over and over.
      if (GM_getValue('rFightList', '') == 'checked') {
          CycleFightList();
      }

      if (inner.indexOf('You <strong>successfully</strong> robbed') != -1) {
        var user;
        var elt = xpath('//td[@class=\'message_body\']//a', messagebox).snapshotItem(0);
        if (elt) {
          user = '<a style="color:#FFD927" href="' + elt.href + '">' +
                 elt.innerHTML + '</a>';
          if (inner.match(/<\/a>('s Mafia of [\d]+)/)) {
           user += RegExp.$1;
          }
        } else {
          addToLog('warning Icon','BUG DETECTED: Unable to read rob name.');
        }
        inner.match(/taking .*?(\d+ damage).*dealing .*?([\d.]+% damage).*(\$[\d,]+).*?(\d+ experience)/);
        var damage_taken = RegExp.$1;
        var damage_dealt = RegExp.$2;
        var gained       = RegExp.$3;
        var experience   = RegExp.$4;
        addToLog('good Icon', '<strong>Robbed </strong>' + user +
                 ' taking ' + '<font style="color:#EC2D2D; font-weight:bold;">' + damage_taken + '</font>' +
                 ' dealing ' + '<font style="color:#52E259; font-weight:bold;">' + damage_dealt + '</font>' +
                 ' gaining ' + '<font style="color:#52E259; font-weight:bold;">' + gained + '</font>'+
                 ' and ' + '<font style="color:#52E259; font-weight:bold;">' + experience + '</font>.');
        if (inner.match(/You put .* out of business!/)) {
          addToLog('good Icon', '<span style="color:#52E259; font-weight:bold;">' + RegExp.lastMatch + '<span>');
        }

        GM_setValue('robWinCountInt', (GM_getValue('robWinCountInt', 0) + 1));
        GM_setValue('totalExpInt', (GM_getValue('totalExpInt', 0) + parseInt(experience)));
        GM_setValue('totalWinDollarsInt', (GM_getValue('totalWinDollarsInt', 0) + parseInt(gained.split('$')[1].replace(/,/g, ''))));
        setFightOpponentRobbed();
      } else if (inner.indexOf('police investigation') != -1) {
        addToLog('process Icon', 'Police investigation. Moving on quietly...');
        setFightOpponentRobbed();
      } else if (inner.indexOf('You <strong>failed</strong> to rob') != -1) {
        var elt = xpath('//td[@class=\'message_body\']//a', messagebox).snapshotItem(0);
        if (elt) {
          user = '<a style="color:#FFD927" href="' + elt.href + '">' +
                 elt.innerHTML + '</a>';
          if (inner.match(/<\/a>('s Mafia of [\d]+)/)) {
           user += RegExp.$1;
          }
        } else {
          addToLog('warning Icon','BUG DETECTED: Unable to read rob name.');
        }
        inner.match(/taking .*?(\d+ damage).*and losing.*(\$[\d,]+)/);
        var damage_taken = RegExp.$1;
        var loss         = RegExp.$2;
        var result = '<strong>Failed</strong> to rob ' + user +
                     ' taking <font style="color:#EC2D2D; font-weight:bold;">' + damage_taken + '</font>' +
                     ' losing <font style="color:#EC2D2D; font-weight:bold;">' + loss + '</font>.';
        result += ' Avoiding.';
        setFightOpponentAvoid();
        addToLog('bad Icon', result);

        loss = parseInt(loss.split('$')[1].replace(/,/g, ''));
        GM_setValue('robLossCountInt', (GM_getValue('robLossCountInt', 0) + 1));
        GM_setValue('totalLossDollarsInt', (GM_getValue('totalLossDollarsInt', 0) + loss));
      } else if (inner.indexOf('You cannot rob') != -1) {
        addToLog('process Icon', 'Removing family member from target list.');
        setFightOpponentAvoid();
      } else {
        // not enough stam or health
        DEBUG('Stamina or health may be too low. Or robbing a nonexistent casino.');
      }

      //Update Rob Statistics
      updateLogStats();
      break;
    case 'stats':
      if (inner.indexOf('You just upgraded your') != -1) {
        switch (GM_getValue('autoStatAdd','')) {
          case 'attack':
            addToLog('process Icon', '<span style="color:#885588;">'+'You upgraded '+ attackIcon + ' attack.</span>');
            break;
          case 'defense':
            addToLog('process Icon', '<span style="color:#885588;">'+'You upgraded '+ defenseIcon + ' defense.</span>');
            break;
          case 'health':
            addToLog('process Icon', '<span style="color:#885588;">'+'You upgraded '+ healthIcon + ' health.</span>');
            break;
          case 'energy':
            addToLog('process Icon', '<span style="color:#885588;">'+'You upgraded '+ energyIcon + ' energy.</span>');
            break;
          case 'stamina':
            addToLog('process Icon', '<span style="color:#885588;">'+'You upgraded '+ staminaIcon + ' stamina.</span>');
          default:
            addToLog('process Icon', '<span style="color:#885588;">'+'You upgraded '+GM_getValue('autoStatAdd')+ '.</span>');
        }
      } else {
        DEBUG('Failed to increment stat: '+ GM_getValue('autoStatAdd'));
      }
      break;
    case 'repair':
      var repairCost = GM_getValue('propertyDamageCost');
      GM_setValue('propertyDamage', 0);
      GM_setValue('propertyDamageCost', 0);
      if (inner.indexOf('You need more cash') != -1) {
        addToLog('warning Icon', 'Someone must have robbed you again before we could repair...');
        var link = 'http://apps.facebook.com/' + SCRIPT.name + SCRIPT.controller + 'property' + SCRIPT.action + 'view';
        takeAction(link, 'propDmgChk');
      } else {
        addToLog('process Icon', 'For <font style="color:#52E259; font-weight:bold;">$'+makeCommaValue(repairCost)+'</font>, you repaired all of your properties.');
        DEBUG(inner);
      }
      break;
    case 'protect':
      var protectCost = GM_getValue('propertyDamageCost');
      GM_setValue('propertyDamage', 0);
      GM_setValue('propertyDamageCost', 0);
      if (inner.indexOf('You need more cash') != -1) {
        addToLog('warning Icon', 'Someone must have robbed you again before we could protect...');
      } else {
        addToLog('process Icon', 'For <font style="color:#52E259; font-weight:bold;">$'+makeCommaValue(protectCost)+'</font>, you protected all of your properties.');
        DEBUG(inner);
      }
      var link = 'http://apps.facebook.com/' + SCRIPT.name + SCRIPT.controller + 'property' + SCRIPT.action + 'view';
      takeAction(link, 'propDmgChk');
      break;
    case 'energypack':
      addToLog('process Icon', energypackIcon + ' Used an <font style="color:#52E259; font-weight:bold;">Energy Pack</font>.');
      addToLog('process Icon', energypackIcon + ' Experience Left To Level Up When EP Used:' + ptsToNextLevel);
      DEBUG('Auto-Energypack Executed, ptsFromEnergyPack=' + ptsFromEnergyPack + ' is less than or equal to ptsToLevelProjStaminaUse=' + ptsToLevelProjStaminaUse);
      DEBUG(inner);
      break;
    case 'propDmgChk':
      // Set GM Value propertyDamage: 0 - no damage, 1 - needs protect, 2 - needs repair & protect
      var protect = xpath('//span[@class=\'sexy_protect\' and contains(text(), \'Protect all properties\')]', doc).snapshotItem(0);
      var repair = xpath('//span[@class=\'sexy_repair\' and contains(text(), \'Repair all properties\')]', doc).snapshotItem(0);
      if ( protect !== null ) {
        dmg = 1;
        cost = parseInt(protect.innerHTML.split('$')[1].replace(/,/g, ''));
        DEBUG('Property is not fully protected, need $'+makeCommaValue(cost));
        GM_setValue('propertyDamage', dmg);
        GM_setValue('propertyDamageCost', cost);
        Autoplay.delay = delay;
        Autoplay.start();
      } else if ( repair !== null ) {
        dmg = 2;
        cost = parseInt(repair.innerHTML.split('$')[1].replace(/,/g, ''));
        DEBUG('Property is not fully repaired, need $'+makeCommaValue(cost));
        GM_setValue('propertyDamage', dmg);
        GM_setValue('propertyDamageCost', cost);
        Autoplay.delay = delay;
        Autoplay.start();
      } else {
        GM_setValue('propertyDamage', 0);
        GM_setValue('propertyDamageCost', 0);
      }
      break;
    case 'deletenews':
      DEBUG('Deleted news feed.');
      break;
    case 'help':
      DEBUG('Parsing job help.');
      var user;
      var elt = messagebox.getElementsByTagName('a')[0];
      if (elt) {
        user = '<a style="color:#FFD927" href="' + elt.href + '">' +
               elt.innerHTML + '</a>';
      }
      if (inner.indexOf('not your friend') != -1) {
        addToLog('info Icon', 'Failed to help. Reason: not friends.');
      } else if (inner.indexOf('You need to be friends') != -1) {
        addToLog('updateBad Icon', 'Failed to help ' + user + ' with job. Reason: not friends.');
      } else if (inner.indexOf('You are too late') != -1) {
          addToLog('info Icon', 'You are too late to help with this job.');
      } else if (inner.indexOf('Not Again') != -1) {
          addToLog('info Icon', 'Already helped ' + user + ' with this job.');
      } else if (inner.indexOf('You received') != -1) {
          var cost = parseInt(inner.split('$')[1].replace(/,/g, ''));
          var experience = parseInt(inner.match(/\d+ experience points/g));
          if (inner.indexOf('Special Bonus') != -1) {
            var loot = inner.split('gained a ')[1];
            addToLog('lootbag Icon', '<span style="color:#FF6633;">'+' Found a '+ loot.split('.<span')[0] + ' while helping on a job.</span>');
          }
          var result = 'You received ' + '<span style="color:#52E259; font-weight:bold;">' +
                   '$' + makeCommaValue(cost) + '</span>' + ' and ' +
                   '<span style="color:#52E259; font-weight:bold;">' + experience + ' experience</span>' +
                   ' for helping ' + user + ' complete the job.';
          addToLog('updateGood Icon', result);
      }
      break;
    default:
      DEBUG('Neither fight nor heal.');
  }
  GM_setValue('actionType','');
}
